28

次のコードでは、監視対象のオブジェクトが更新されますが、それを監視するビューは更新されません。理由はありますか?

コードは、画面に 10 個の数字 (0..<10) とボタンを表示します。ボタンが押されるたびに、10 個の数字の 1 つがランダムに選択され、その可視性が反転します (可視→非表示、またはその逆)。

print ステートメントは、ボタンが数値を更新していることを示していますが、ビューはそれに応じて更新されません。配列の値を更新しても配列の値自体は変更されないことがわかっているので、手動objectWillChange.send()呼び出しを使用します。それが更新をトリガーするはずだと思っていたでしょうが、画面は決して変わりません。

何か案が?NumberLineクラスまたは構造体として使用するか、NumberLine型をまったく使用せず、代わりに構造体内で配列変数を使用するソリューションに興味がありますContentView

スクリーンショット

コードは次のとおりです。

import SwiftUI

struct ContentView: View {

    @ObservedObject var numberLine = NumberLine()

    var body: some View {
        VStack {
            HStack {
                ForEach(0 ..< numberLine.visible.count) { number in
                    if self.numberLine.visible[number] {
                        Text(String(number)).font(.title).padding(5)
                    }
                }
            }.padding()

            Button(action: {
                let index = Int.random(in: 0 ..< self.numberLine.visible.count)
                self.numberLine.objectWillChange.send()
                self.numberLine.visible[index].toggle()
                print("\(index) now \(self.numberLine.visible[index] ? "shown" : "hidden")")
            }) {
                Text("Change")
            }.padding()
        }
    }
}

class NumberLine: ObservableObject {
    var visible: [Bool] = Array(repeatElement(true, count: 10))
}
4

4 に答える 4

9

私は同じ問題に直面しました。私にとっては、@ObservedObject@StateObjectに置き換えるとうまくいきました。

于 2021-04-01T08:56:58.157 に答える
0

観察されたオブジェクトに問題はありません。観察されたオブジェクト使用@Publishedする必要がありますが、私のコードはそれがなくても機能します。また、コードのロジックを更新しました。


ここに画像の説明を入力


import SwiftUI

struct ContentView: View {
    
    @ObservedObject var model = NumberLineModel()
    @State private var lastIndex: Int?
    
    var body: some View {
        
        VStack(spacing: 30.0) {
            
            HStack {
                
                ForEach(0..<model.array.count) { number in
                    
                    if model.array[number] {
                        Text(String(number)).padding(5)
                    }
                    
                }
                
            }
            .font(.title).statusBar(hidden: true)
            
            Group {
                
                if let unwrappedValue: Int = lastIndex { Text("Now the number " + unwrappedValue.description + " is hidden!") }
                else { Text("All numbers are visible!") }
                
            }
            .foregroundColor(Color.red)
            .font(Font.headline)
            
            
            
            Button(action: {
                
                if let unwrappedIndex: Int = lastIndex { model.array[unwrappedIndex] = true }
                
                let newIndex: Int = Int.random(in: 0...9)
                model.array[newIndex] = false
                lastIndex = newIndex
                
                
            }) { Text("shuffle") }
            
        }
        
    }
}

class NumberLineModel: ObservableObject {
    
    var array: [Bool] = Array(repeatElement(true, count: 10))
    
}

于 2021-04-01T10:47:12.387 に答える