如何在SwiftUI单词拼图游戏中高亮数组中的单词?
问题解决:SwiftUI单词搜索网格高亮所有目标单词字符
问题根源
你的代码存在两个核心问题:
findWord()函数在找到第一个匹配的单词起始位置后立即return true,不会继续检查后续单词;- 逻辑方向错误:当前仅判断格子是否是单词的起始位置,而非格子是否属于某个目标单词的任意位置,导致只能高亮单词的第一个字符,无法覆盖整个单词。
解决方案
我们可以预先计算出所有需要高亮的坐标集合,这样既提升性能,又能准确覆盖所有目标单词的字符。
修改后的完整代码
import SwiftUI struct WordSearchGameView: View { let wordsToFind = ["hello", "hay"] let gridSize = 5 @State var grid: [[Character]] = [ ["h", "e", "l", "l", "o"], ["a", "c", "c", "a", "i"], ["g", "i", "a", "h", "c"], ["h", "a", "o", "a", "l"], ["e", "o", "l", "y", "s"] ] // 预计算所有需要高亮的坐标集合 private var highlightedPositions: Set<(row: Int, col: Int)> { var positions = Set<(Int, Int)>() for word in wordsToFind { // 遍历网格所有可能的起始位置 for row in 0..<gridSize { for col in 0..<gridSize { // 检查所有方向,若找到单词则添加所有字符坐标到集合 let directions = [(0,1), (1,0), (1,1), (-1,0), (0,-1), (-1,-1), (1,-1), (-1,1)] for dir in directions { if let wordPositions = findWordPositions(word: word, startRow: row, startCol: col, dir: dir) { positions.formUnion(wordPositions) } } } } } return positions } var body: some View { VStack(spacing: 0) { ForEach(0..<gridSize, id: \.self) { row in HStack(spacing: 0) { ForEach(0..<gridSize, id: \.self) { col in Text(String(grid[row][col])) .frame(maxWidth: .infinity, maxHeight: .infinity) .background(highlightedPositions.contains((row, col)) ? Color.yellow : Color.white) } } } } } // 修改为返回单词的所有坐标(若存在),否则返回nil func findWordPositions(word: String, startRow: Int, startCol: Int, dir: (Int, Int)) -> [(Int, Int)]? { guard word.count <= gridSize else { return nil } var positions = [(Int, Int)]() var currentRow = startRow var currentCol = startCol for charIndex in 0..<word.count { // 检查边界和字符匹配 guard currentRow >= 0, currentRow < gridSize, currentCol >= 0, currentCol < gridSize, grid[currentRow][currentCol] == word[word.index(word.startIndex, offsetBy: charIndex)] else { return nil } positions.append((currentRow, currentCol)) currentRow += dir.0 currentCol += dir.1 } return positions } } struct WordSearchGameView_Previews: PreviewProvider { static var previews: some View { WordSearchGameView() } }
关键修改说明
预计算高亮集合:
- 创建
highlightedPositions计算属性,遍历所有目标单词、所有网格起始位置和所有方向,收集所有属于目标单词的字符坐标。 - 使用
Set存储坐标,避免重复添加同一位置(比如多个单词重叠的情况)。
- 创建
修改方向检查函数:
- 将原有的布尔判断函数改为
findWordPositions,返回匹配单词的所有坐标数组(若成功),一次性获取整个单词的所有字符位置。
- 将原有的布尔判断函数改为
视图逻辑简化:
- 绘制格子时直接查询预计算的集合,判断是否需要高亮,既简化代码又提升性能,避免每个格子重复执行多次方向检查。
内容的提问来源于stack exchange,提问作者Emma
相关产品推荐
相关产品推荐

