首页 > 解决方案 > 使用 Combine 和 SwiftUI 对点击的按钮进行更改

问题描述

isValid在用户从Menu正确的位置选择后尝试更改。

如果我先选择一个职位,然后在文本字段中输入电子邮件和姓名,而不是另一边,这似乎可行。

我想Button在他选择职位并完成其他文本字段时启用。

class EmployeeModel: ObservableObject{
    
    @Published var employee: Employee
    @Published var isValid = false
    
    private var cancellables = Set<AnyCancellable>()
    
    init(employee: Employee = Employee(uid: "", affiliate: 0, employeeID: 1, email: "", name: "", shiftsConstIsApplied: false, position: nil, shiftConsts: nil, pushId: "")){
        
        self.employee = employee
        
        self.$employee
            .debounce(for: 0.5, scheduler: RunLoop.main)
            
            .map({!$0.name.isEmpty && !$0.email.isEmpty && $0.position != nil})
            .sink{ input in
                print(input)
                self.isValid = input
            }
            .store(in: &cancellables)
    }
}

风景:


@State private var position: Positions?
@StateObject var employeeModel = EmployeeModel()

Menu(LocalizedStringKey(self.$position.wrappedValue?.rawValue ?? "Choose position")) {
                        ForEach(Positions.employeeTypes, id:\.self){ p in
                            Button(LocalizedStringKey(p)){
                                let positionSelected = Positions(rawValue: p)
                                self.position = positionSelected
                                self.employeeModel.employee.position = positionSelected
                            }
                        }
                    }

Button("Confirm"){
//do something
}
.disabled(!self.employeeModel.isValid)

将 Employee 建模为 ObservableObject:

    @Published var uid: String?
    @Published var email: String
    @Published var name: String
    @Published var affiliate: Int?
    @Published var employeeId: Int?
    @Published var shiftsConstIsApplied: Bool? = true
    @Published var position: Positions?
    @Published var shiftConsts: [ShiftConst]?

标签: iosswiftforeachswiftuicombine

解决方案


如果我正确理解了您的代码,请尝试以下操作(未经测试!)

init(employee: Employee = Employee(uid: "", affiliate: 0, employeeID: 1, email: "", name: "", shiftsConstIsApplied: false, position: nil, shiftConsts: nil, pushId: "")){
    
    self.employee = employee
    
    self.employee.objectWillChange               // << here !!
        .debounce(for: 0.5, scheduler: RunLoop.main)

,你不改变员工本身(因为它是引用类型),而只是它的内部属性,所以你需要订阅它的内部发布者。


推荐阅读