Как выполнить обновление вычисляемого свойства привязки для класса ObservableObject?

#swiftui

#swiftui

Вопрос:

У меня есть этот класс:

 class MyModel:ObservableObject {
  
  var selectedObjectIndex:Int {
    set {}
    get {
      let selectedResult = objects.filter({ $0 == selectedObject })
      if selectedResult == 0 { return 0 }
      return objects.firstIndex(of: selectedResult.first!)!
    }
  }
}
 

selectedObjectIndex Обычно это было бы a @Published var selectedObjectIndex:Int , но поскольку это вычисляемое свойство, я не могу его использовать @Published .

Поэтому я был вынужден добавить это в модель

 func getselectedObjectIndexBinding() -> Binding<Int> { 
  let binding = Binding<Int>(
    get: { () -> Int in
      return self.selectedObjectIndex
    }) { (newValue) in
    self.selectedObjectIndex = newValue
  }
  return binding
}
 

В представлении у меня есть средство выбора, использующее это как

 Picker(selection: myModel.getselectedObjectIndexBinding(),
       label: Text("select")) {
 

Средство выбора отображается правильно, но если я установлю для него новое значение, модель selectedObjectIndex не будет обновлена.

Комментарии:

1. Ваш метод set для selectedObjectIndex ничего не делает

2. как мне это решить?

3. Это зависит от того, что вы хотите сохранить (т.Е. Сохранить) selectedObjectIndex.set . Из вашего кода намерение неясно — не могли бы вы уточнить подробнее?

Ответ №1:

Вы можете попробовать что-то вроде приведенного ниже: всякий раз, когда привязка обновляется, вы selectedObjectIndex можете запускать ObjectWillChange уведомление после выполнения некоторой соответствующей работы. Я создал selectedObjectIndex as propertyObserver .

 struct CreditCardFront: View {
    
    @ObservedObject var myModel:MyModel
   
   
    var body: some View {
        
        Picker(selection: myModel.getselectedObjectIndexBinding(),
               label: Text("select")) {
            
            ForEach(1..<10) { value in
                Text("(value)")
            }
        }
        Text("(myModel.selectedObjectIndex ?? 0)")
        
    }
    
    
}

class MyModel:ObservableObject {
    
    var selectedObjectIndex:Int?{
        didSet{
            // Your work here
            update() // call notification on specific change
        }
    }
    
    func getselectedObjectIndexBinding() -> Binding<Int> {
        let binding = Binding<Int>(
            get: { () -> Int in
                return self.selectedObjectIndex ?? 0
            }) { (newValue) in
            self.selectedObjectIndex = newValue
        }
        return binding
    }
    
    func update(){
        self.objectWillChange.send()
    }
}
 

@main-:

 @main
struct WaveViewApp: App {
    @StateObject var model:MyModel
    init() {
        let model = MyModel()
        _model = StateObject(wrappedValue: model)
    }
    
    var body: some Scene {
        WindowGroup {
            CreditCardFront(myModel: model)
        }
    }
}
 

Комментарии:

1. Почему бы не просто @StateObject var model = MyModel() ?

2. @pawello2222 мы определенно могли бы это сделать, но у меня был старый фрагмент кода, написанный таким образом, который я только что изменил.