SwiftUI görünümlerinin iç içe ObservableObjects'e nasıl bağlanacağını söyleme


18

Ben adlandırılan bir EnvironmentObject alır bir SwiftUI görünüm var appModel. Daha sonra değerini okur appModel.submodel.countonun içinde bodyyöntemle. Ben özellik güncellemeleri zaman yeniden oluşturur count, submodelböylece bu özelliği görünümüne bağlamak için bekliyoruz , ama bu gerçekleşmiyor gibi görünüyor.

Bu bir hata mı? Ve değilse, görünümlerin SwiftUI'deki ortam nesnelerinin iç içe özelliklerine bağlanmasının deyimsel yolu nedir?

Özellikle, modelim şöyle görünüyor ...

class Submodel: ObservableObject {
  @Published var count = 0
}

class AppModel: ObservableObject {
  @Published var submodel: Submodel = Submodel()
}

Benim görüşüm şöyle ...

struct ContentView: View {
  @EnvironmentObject var appModel: AppModel

  var body: some View {
    Text("Count: \(appModel.submodel.count)")
      .onTapGesture {
        self.appModel.submodel.count += 1
      }
  }
}

Uygulamayı çalıştırıp etikete tıkladığımda countözellik artar, ancak etiket güncellenmez.

Bunu appModel.submodelbir özellik olarak geçirerek düzeltebilirim ContentView, ancak mümkünse bunu yapmaktan kaçınmak istiyorum.


Uygulamamı da böyle tasarlıyorum. Genellikle geçmiş uygulama geliştirmede global bir Uygulama nesnesim var. Çevre değişkeni olarak süper bir "Uygulama" sınıfının bu tasarımının standart uygulama haline geleceğini düşünen var mı? Ben de birden fazla EnvironmentObjects kullanmayı düşünüyordum ama bu bakımı zordu.
Michael Ozeryansky

Yanıtlar:


22

İç içe modeller henüz SwiftUI'de çalışmıyor, ancak böyle bir şey yapabilirsiniz

class Submodel: ObservableObject {
    @Published var count = 0
}

class AppModel: ObservableObject {
    @Published var submodel: Submodel = Submodel()

    var anyCancellable: AnyCancellable? = nil

    init() {
        anyCancellable = submodel.objectWillChange.sink { (_) in
            self.objectWillChange.send()
        }
    } 
}

Temel olarak AppModeletkinliğinizden olayı yakalar Submodelve daha sonra Görünüm'e gönderir

Düzenle:

SubModelSınıf olmanız gerekmiyorsa , böyle bir şey de deneyebilirsiniz:

struct Submodel{
    var count = 0
}

class AppModel: ObservableObject {
    @Published var submodel: Submodel = Submodel()
}

Teşekkürler, bu yardımcı olur! "İç içe modeller henüz SwiftUI'de çalışmaz" dediğinizde, bunların planlandığından emin misiniz?
rjkaplan

Emin değilim, ama bence işe yaramalı, projemde de benzer bir şey kullanıyorum, bu yüzden daha iyi bir yaklaşım bulursam bir düzenleme ile geleceğim
Sorin Lica

Should @SorinLica Submodelolmak ObservableObject türünü?
Farhan Amjad

İşe yarıyor! Müthiş bir çözüm!
Md Shahed Hossain

1

Her üç ViewModel de iletişim kurabilir ve güncelleyebilir

// First ViewModel
class FirstViewModel: ObservableObject {
var facadeViewModel: FacadeViewModels

facadeViewModel.firstViewModelUpdateSecondViewModel()
}

// Second ViewModel
class SecondViewModel: ObservableObject {

}

// FacadeViewModels Combine Both 

import Combine // so you can update thru nested Observable Objects

class FacadeViewModels: ObservableObject { 
lazy var firstViewModel: FirstViewModel = FirstViewModel(facadeViewModel: self)
  @Published var secondViewModel = secondViewModel()
}

var anyCancellable = Set<AnyCancellable>()

init() {
firstViewModel.objectWillChange.sink {
            self.objectWillChange.send()
        }.store(in: &anyCancellable)

secondViewModel.objectWillChange.sink {
            self.objectWillChange.send()
        }.store(in: &anyCancellable)
}

func firstViewModelUpdateSecondViewModel() {
     //Change something on secondViewModel
secondViewModel
}

Kombine çözüm için Sorin'e teşekkür ederiz.


Kodu güncelleyebilir misiniz? birçok derleyici hatası var
DevB2F

-2

Böcek gibi görünüyor. Xcode'u en son sürüme güncellediğimde, iç içe ObservableObjects'e bağlanırken düzgün çalışıyor


Şu anda hangi xcode sürümünü kullandığınızı açıklığa kavuşturabilir misiniz? Şu anda Xcode 11.0'ım var ve bu sorunu yaşıyorum. 11.1'e yükseltme konusunda sorun yaşadım,% 80 tamamlanmış gibi geçmeyecek.
Michael Ozeryansky
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.