您可以将Publisher直接用作SwiftUI中的@ObjectBinding属性吗?

时间:2019-06-22 20:24:37

标签: swift macos swiftui

在SwiftUI中,您可以直接将Publisher的实例用作@ObjectBinding属性,还是必须将其包装在实现BindableObject的类中?

let subject = PassthroughSubject<Void, Never>()
let view = ContentView(data:subject)

struct ContentView : View {
  @ObjectBinding var data:AnyPublisher<Void, Never>
}

// When I want to refresh the view, I can just call: 
subject.send(())

这不是为我编译的文件,只是挂起了Xcode 11 Beta2。但是您甚至应该被允许这样做吗?

2 个答案:

答案 0 :(得分:17)

在您的View正文中,使用.onReceive传递发布者,如下例,取自Data Flow Through SwiftUI - WWDC 2019 @ 21:23。在闭合内部,您将更新状态,该状态又将在身体的其他位置使用。

enter image description here

这是我制作的一个有效示例:

import SwiftUI
import Combine

class ContentViewModel : ObservableObject{
    @Published
    var password : String=""

    @Published
    var passwordAgain : String=""

    var validatedPassword: AnyPublisher<(String)?, Never>{
        return Publishers.CombineLatest($password, $passwordAgain)
        .map { password, passwordAgain in
                guard password == passwordAgain, password.count > 0 else { return nil }
                return password
        }
        .eraseToAnyPublisher()
    }
}

struct ContentView: View {

    @ObservedObject
    var contentViewModel = ContentViewModel()

    @State
    var buttonDisabled: Bool = true

    var body: some View {
        VStack{
            Text("Hello, World!")
            SecureField("Password", text: self.$contentViewModel.password)
            SecureField("Password Again", text: self.$contentViewModel.passwordAgain)

            Button(action: {
            }){
                Text("Submit")
                .disabled(buttonDisabled)
            }
        }
        .onReceive(contentViewModel.validatedPassword) { password in
            self.buttonDisabled = password == nil
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

答案 1 :(得分:1)

您可以实现以发布者为初始化参数的const myTheme = createMuiTheme({ overrides: { Datagrid: { header: { fontWeight: 'bold', } } } }) const App = () => ( <Admin theme={myTheme}> // ... </Admin> );

并使用方便功能扩展BindableObject以创建此Publisher

BindableObject