Невозможно преобразовать значение типа «Опубликовано <Bool>.Publisher» в ожидаемый тип аргумента «Binding <Bool>» - PullRequest
2 голосов
/ 06 августа 2020

При попытке скомпилировать следующий код:

class LoginViewModel: ObservableObject, Identifiable {
    @Published var mailAdress: String = ""
    @Published var password: String = ""
    @Published var showRegister = false
    @Published var showPasswordReset = false

    private let applicationStore: ApplicationStore

    init(applicationStore: ApplicationStore) {
        self.applicationStore = applicationStore
    }

    var passwordResetView: some View {
        PasswordResetView(isPresented: $showPasswordReset) // This is where the error happens
    }
}

Где PasswordResetView выглядит так:

struct PasswordResetView: View {
    @Binding var isPresented: Bool
    @State var mailAddress: String = ""
    
    var body: some View {
            EmptyView()
        }
    }
}

Я получаю ошибку при компиляции

Cannot convert value of type 'Published<Bool>.Publisher' to expected argument type 'Binding<Bool>'

Если я использую опубликованную переменную вне класса LoginViewModel, она просто отлично работает:

struct LoginView: View {
    @ObservedObject var viewModel: LoginViewModel

    init(viewModel: LoginViewModel) {
      self.viewModel = viewModel
    }
    
    var body: some View {
            PasswordResetView(isPresented: self.$viewModel.showPasswordReset)
    }
}

Есть предложения, что я здесь делаю неправильно? Есть ли шанс передать опубликованную переменную в качестве привязки из класса-владельца?

Спасибо!

Ответы [ 2 ]

1 голос
/ 06 августа 2020

** Все еще новичок в Combine и SwiftUI, поэтому не уверен, есть ли лучший способ приблизиться к **

Вы можете инициализировать привязку от издателя.

https://developer.apple.com/documentation/swiftui/binding/init (получить : set:) - 6g3d5

let binding = Binding(
    get: { [weak self] in
        (self?.showPasswordReset ?? false)
    },
    set: { [weak self] in
        self?.showPasswordReset = $0
    }
)

PasswordResetView(isPresented: binding)

0 голосов
/ 06 августа 2020

Вот возможный подход - идея сделать возможным наблюдение в сгенерированном виде и избежать тесной связи между фабрикой и презентатором.

Протестировано с Xcode 12 / iOS 14 (для старых систем может потребоваться некоторая настройка )

protocol ResetViewModel {
    var showPasswordReset: Bool { get set }
}

struct PasswordResetView<Model: ResetViewModel & ObservableObject>: View {
    @ObservedObject var resetModel: Model

    var body: some View {
        if resetModel.showPasswordReset {
            Text("Show password reset")
        } else {
            Text("Show something else")
        }
    }
}

class LoginViewModel: ObservableObject, Identifiable, ResetViewModel {
    @Published var mailAdress: String = ""
    @Published var password: String = ""
    @Published var showRegister = false
    @Published var showPasswordReset = false

    private let applicationStore: ApplicationStore

    init(applicationStore: ApplicationStore) {
        self.applicationStore = applicationStore
    }

    var passwordResetView: some View {
        PasswordResetView(resetModel: self)
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...