SwiftUI | Сложные структуры данных обновляющие UI

Имею довольно сложную структуру данных, класс с большим количеством переменных, являющимися экземплярами других классов. В каждой из этих переменных есть UInt16 значение и String get-set переменная, ответственная за форматированный ввод-вывод этих значений.

Значение внутри определённых экземпляров классов изменяются через TextField в UI программы, что работает, внутри других же изменяются в результате действий функции в одном из вложенных экземпляров, что не работает (соединены друг с другом с помощью Binding).

Настоящим решением является добавление @Published var updater: Bool переменной в основной класс и привязывание её в класс с функцией, с последующим вызовом .toggle() в конце работы. Но данное решение работает не совсем корректно, не говоря уже о том, что это вряд ли оно в какой-либо степени правильное.

Далее код основного класса:

class Computer: ObservableObject
{
    @Published var updater: Bool = false
    
    @Published var program: Program = Program()
    
    @Published var shift: Shift = Shift()
    @Published var accumulator: Accumulator = Accumulator()
    @Published var commandCounter: CommandCounter = CommandCounter()
    @Published var addressRegister: AddressRegister = AddressRegister()
    @Published var commandRegister: CommandRegister = CommandRegister()
    @Published var dataRegister: DataRegister = DataRegister()
    @Published var statusRegister: StatusRegister = StatusRegister()
    
    @Published var arithmeticLogicUnit: ArithmeticLogicUnit = ArithmeticLogicUnit()
    
    @Published var externalDevices: [ExternalDevice] = [ExternalDevice(), ExternalDevice(), ExternalDevice()]
    
    @Published var microCommandManager: MicroCommandManger = MicroCommandManger()
    
}

Классы, чьи экземпляры находятся в основном классе ничего не наследуют, их переменные ничем не обёрнуты, в некоторых из них есть @Binding переменные для получения необходимых данных. (Добавление Binding в переменные осуществляется в init() класса, который я опустил за ненадобностью)

Экземпляр основного класса добавлен к View как .enviromentObject()

Что именно нужно сделать с переменными, чтобы при изменения значений в экземплярах обновлялся UI?


Ответы (1 шт):

Автор решения: Andrew

тебе нужно 2 инстанса - вьюха и модель.

вот пример модели

class ComputerViewModel: ObservableObject{
    @Published var videocard: String = "RTX..."
    ///...........
}

вот пример вьюхи:

struct ComputerView: View {
    @ObservedObject var model: BrowserViewModel
    var body: some View {
        //здесь ты обращаешся к model.videocard
        VStack{
           Text("сейчас стоит видяха: {model.videocard}")

           TextField($model.videocard)
        }
        
  
    }
}

важно понимать для работы то, что если ты хочешь коректной работы с вью-моделью -

  1. viewModel должна быть обсервейбл и внутри вьюхи инстанс -- обсерведом.
  2. для автообновления вьюхи все во viewModel должно быть структурами, а не обьектами класса.

других сложностей вроде нет.

код писал из головы непроверяя, так что могут быть мелкие синтаксические ошибки.

→ Ссылка