首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >无法将“Published<Bool>.Publisher”类型的值转换为预期的参数类型“Binding<Bool>”

无法将“Published<Bool>.Publisher”类型的值转换为预期的参数类型“Binding<Bool>”
EN

Stack Overflow用户
提问于 2020-08-06 11:14:32
回答 5查看 27K关注 0票数 40

当试图编译以下代码时:

代码语言:javascript
运行
复制
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看起来是这样的:

代码语言:javascript
运行
复制
struct PasswordResetView: View {
    @Binding var isPresented: Bool
    @State var mailAddress: String = ""
    
    var body: some View {
            EmptyView()
        }
    }
}

我得到错误编译错误

代码语言:javascript
运行
复制
Cannot convert value of type 'Published<Bool>.Publisher' to expected argument type 'Binding<Bool>'

如果我在LoginViewModel类之外使用已发布的变量,它就能正常工作:

代码语言:javascript
运行
复制
struct LoginView: View {
    @ObservedObject var viewModel: LoginViewModel

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

我在这里做错了什么有什么建议吗?是否有可能将已发布的变量从所属类中作为绑定传递?

谢谢!

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2020-08-06 17:48:56

这是一种可能的方法--在生成的视图中进行可能的观察,并避免工厂和演示者之间的紧密耦合。

用Xcode 12 / iOS 14进行测试(对于旧系统,可能需要进行一些调优)

代码语言:javascript
运行
复制
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)
    }
}
票数 5
EN

Stack Overflow用户

发布于 2022-02-12 11:51:30

不知道为什么这里提出的解决方案如此复杂,当有一个非常直接的解决办法。

类似Reddit问题上找到了这个答案

问题是,当您访问@观测台对象(这是一个绑定)的投影值时,您访问的是@ globalSettings.$tutorialView的投影值(它是一个发布者),也就是说:您拥有$globalSettings.tutorialView的位置。

票数 59
EN

Stack Overflow用户

发布于 2020-08-06 11:44:30

**仍然是新的组合& SwiftUI不确定是否有更好的方法来接近**

您可以从publisher中初始化绑定。

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

代码语言:javascript
运行
复制
let binding = Binding(
    get: { [weak self] in
        (self?.showPasswordReset ?? false)
    },
    set: { [weak self] in
        self?.showPasswordReset = $0
    }
)

PasswordResetView(isPresented: binding)
票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63282377

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档