У меня есть ParentView, из которого я хочу передать переменную @Published в Subview, где она будет использоваться как @ Bindable.
Это работает при использовании MyViewModel следующим образом:
class MyViewModel: ObservableObject {
@Published var soundOn = true
}
struct ParentView: View {
@ObservedObject var myViewModel: MyViewModel
var body: some View {
Subview(soundOn: $myViewModel.soundOn)
}
}
struct Subview: View {
@Binding var soundOn: Bool
var body: some View {
Image(soundOn ? "soundOn" : "soundOff")
}
}
но я хочу повторно использовать Subview для всех ViewModels, соответствующих протоколу HasSoundOnOff. При использовании протокола HasSoundOnOff я не могу определить @Published внутри протокола, а это означает, что ParentView видит только обычную переменную non-@Published и не может использовать $ viewModel.soundOn.
protocol HasSoundOnOff {
var soundOn: Bool { get set }
}
class MyViewModel: HasSoundOnOff {
@Published var soundOn = true
}
struct ParentView<ViewModel: ObservableObject & HasSoundOnOff>: View {
@ObservedObject var viewModel: ViewModel
var body: some View {
Subview(soundOn: $viewModel.soundOn) //<----- error: "Expression type 'Binding<_>' is ambiguous without more context" because protocols can't have @Published and therefor soundOn is treated like a non-@Published variable
}
}
Я могу разрешить MyViewModel наследовать от класса, который определяет переменную @Published, поэтому работает следующий код:
class InheritFromPublishedVarClass: ObservableObject {
@Published var soundOn = true
}
class MyViewModel: ObservableObject & InheritFromPublishedVarClass {}
struct ParentView<ViewModel: ObservableObject & InheritFromPublishedVarClass>: View {
@ObservedObject var viewModel: ViewModel
var body: some View {
Subview(soundOn: $viewModel.soundOn)
}
}
Это означает, что я могу повторно использовать мою переменную @Published, но это не будет масштабироваться, поскольку множественное наследование не разрешено.
Это серьезно ограничивает возможность повторного использования кода для меня. Должен быть способ добиться этого более масштабируемым образом. Любые идеи? Требуется, чтобы ParentView принимал параметр Generi c ViewModel.