结构体状态变量的问题

问题描述 投票:0回答:1

我正在为 iOS 制作数独,这对于我的课程来说将是一个简单的项目。问题在于数独的检查。检查的数独可能会出现三个结果:

  1. 未填写
  2. 正确
  3. 不正确

根据这些值的枚举,将会有一个工作表显示已检查的数独的结果。

列举如下:

// MARK: Statuses
/// Statuses that can result from checking the sudoku.
enum Statuses {
    case correct
    case incorrect
    case notFilled
}

这是保存枚举值和用于显示工作表的布尔变量的结构。

// MARK: SudokuStatus
/// Struct that is used to combine the status and if the sudoku is checked.
struct SudokuStatus {
    public var status: Statuses
    public var isChecked: Bool
    
    /// Initialiser of the struct making the status not checked and empty.
    init () {
        self.status = .notFilled
        self.isChecked = false
    }
    
    /// Function that will update the status.
    /// - Parameter status: The status form the sudoku.
    /// - Returns: There is no return.
    mutating func setStatus(status: Statuses) -> Void {
        self.status = status
        self.isChecked = true
    }
}

这是内容视图。

// MARK: ContentView
/// The main view of the app.
struct ContentView: View {
    /// Variable that will create a sudoku object.
    let sudoku: Sudoku = Sudoku()
    /// Array that will hold the numbers in the sudoku.
    /// If the numbers is equals to 0 it means its empty.
    @State var numbers: [[Number]] = Array(repeating: Array(repeating: Number(), count: 9), count: 9)
    /// Variable that will keep the selected number.
    /// The value at begging will be 0 representing that no number is selected.
    @State var selectedNumber: Int = 0
    /// Variable used to selected the difficulty of the game.
    @State var selectedDifficulty: Difficulties = .easy
    /// Variable that will keep the status form the sudoku.
    @State var sudokuStatus: SudokuStatus = SudokuStatus()
    
    /// The main body of the struct.
    var body: some View {
        GeometryReader { geo in
            VStack(spacing: geo.size.height / 20) {
                Title (
                    width: geo.size.width / 1.2,
                    height: geo.size.height / 10
                )
                
                Board (
                    size: geo.size.width / 1.2,
                    selectedNumber: $selectedNumber,
                    numbers: $numbers
                )
                
                NumberSelection (
                    width: geo.size.width,
                    height: geo.size.height / 10,
                    selectedNumber: $selectedNumber
                )
                
                BottomBar (
                    width: geo.size.width,
                    height: geo.size.height / 10,
                    onStartGameClicked: onStartGameClicked,
                    onCheckGameClicked: onCheckGameClicked,
                    selectedDifficulty: $selectedDifficulty
                )
            }
            .frame(maxWidth: .infinity, maxHeight: .infinity)
            .sheet(isPresented: $sudokuStatus.isChecked, content: {
                SudokuStatusSheet(status: sudokuStatus.status)
            })
        }
    }
    
    /// Function called when the start button is clicked.
    /// - Returns: There is no return. The function fills the array with the numbers.
    func onStartGameClicked() -> Void {
        let grid: [[Int]] = sudoku.generateSudoku(difficulty: selectedDifficulty)
        for i in 0..<9 {
            for j in 0..<9 {
                if grid[i][j] == 0 {
                    numbers[i][j].value = 0
                    numbers[i][j].isGenerated = false
                }
                else {
                    numbers[i][j].value = grid[i][j]
                    numbers[i][j].isGenerated = true
                }
            }
        }
    }
    
    /// Function called when the check button is clicked.
    /// - Returns: There is no return. The function updates the sudoku status variable.
    func onCheckGameClicked() -> Void {
        var grid: [[Int]] = Array(repeating: Array(repeating: 0, count: 9), count: 9)
        for i in 0..<9 {
            for j in 0..<9 {
                if numbers[i][j].value == 0 {
                    sudokuStatus.setStatus(status: .notFilled)
                    return
                }
                grid[i][j] = numbers[i][j].value
            }
        }
        
        if Sudoku.checkSudoku(grid: grid) {
            sudokuStatus.setStatus(status: .correct)
        } else {
            sudokuStatus.setStatus(status: .incorrect)
        }
    }
}

如您所见,检查数独的功能非常简单。它通过保存数字值的结构体和 bool 变量来检查输入的数字,以检查该数字是否由用户生成或输入。如果数字等于0,则表示为空,会将值更新为未填充并返回。然后它将由班级进行检查 数独可以正确工作,如果结果为真,它将使其从正确变为错误。问题是,每次应用程序启动或预览重新启动时,您第一次检查数独时,它总是会显示未填充。之后代码就可以正常工作,但第一次检查时就不行了。

我更改了结构数独状态的默认初始化程序的值,并了解到将显示的第一个值将是设置的默认值。我真的不知道如何解决这个问题,所以我没有尝试更多,除了在互联网上搜索同样的问题,或者使用我们最喜欢的人工智能,但它没有帮助。

swift swiftui sudoku
1个回答
0
投票

最好的方法是创建一个符合

ObservableObject
并具有
@Published
值的类,如下所示:

class SudokuStatus: ObservableObject {
    @Published var status: Statuses = .notFilled
    @Published var isChecked: Bool = false
    
    func setStatus(status: Statuses) {
        self.status = status
        self.isChecked = true
    }
}

然后,您必须将此对象声明为

@StateObject
,并像您一样使用它,如下所示:

@StateObject var sudokuStatus: SudokuStatus = .init()

//...

            .sheet(isPresented: $sudokuStatus.isChecked) {
                SudokuStatusSheet(status: sudokuStatus.status)
            }

//...
© www.soinside.com 2019 - 2024. All rights reserved.