簡體   English   中英

無法轉換“已發布”類型的值<bool> .Publisher'到預期的參數類型'綁定<bool> '</bool></bool>

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

嘗試編譯以下代碼時:

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 class 外部的已發布變量,它就可以正常工作:

struct LoginView: View {
    @ObservedObject var viewModel: LoginViewModel

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

有什么建議我在這里做錯了嗎? 我有沒有機會從擁有的 class 內部將已發布的變量作為綁定傳遞?

謝謝!

** 組合和 SwiftUI 仍然是新手,所以不確定是否有更好的方法來接近 **

您可以從發布者初始化綁定。

https://developer.apple.com/documentation/swiftui/binding/init(get:set:)-6g3d5

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

PasswordResetView(isPresented: binding)

這是可能的方法 - 在生成的視圖中進行可能的觀察並避免工廠和演示者之間的緊密耦合的想法。

使用 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)
    }
}

我認為這里要理解的重要一點是“$”在組合上下文中的作用。

"$" 所做的是將變量 "showPasswordReset" 的變化發布在被觀察的地方。

當它在類型之前時,它不代表您為變量聲明的類型(在這種情況下為布爾值),它代表發布者,如果您想要類型的值,只需刪除“$”。

"$" 用於將變量標記為@ObservedObject 的上下文中,(此處的 ObservableObject 是 LoginViewModel,您訂閱它以作為發布者偵聽其變量市場的變化)

struct ContentView: View {
       @ObservedObject var loginViewModel: LoginViewModel...

在這種情況下(例如 ContentView),“showPasswordReset”的更改將在其值更新時“發布”,因此視圖會使用新值更新。

對於聲明:“無法將'Binding'類型的值轉換為預期的參數類型'Bool'”的錯誤,解決方案是使用wrappedValue,如下例所示。

如果您有帶有屬性 isEnabled 的 MyObject object 並且您需要將其用作 vanilla Bool 類型而不是 'Binding' 然后執行 myView.disabled($myObject.isEnabled.wrappedValue)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM