使字符串和颜色可绑定

Make string and color bindable

我有一些类似下面的代码,我想通过 SwiftUI 的绑定更新字符串和颜色,但我收到这些错误:

Initializer 'init(_:)' requires that 'Binding' conform to 'StringProtocol'

Cannot convert value of type 'Binding' to expected argument type 'Color?'

import SwiftUI

struct PasswordStrengthIndicator: View {
    private let segment = RoundedRectangle(cornerRadius: CGFloat(4))

    @State private var segmentColor = Color.gray
    @State private var hintText = ""

    var body: some View {
       VStack {
           segment
               .foregroundColor($segmentColor)
           Text($hintText)
       }
       .onAppear(perform: onAppear)
    }

    func onAppear() {
       segmentColor = Color.red
       hintText = "Enter password!"
    }
}

如果删除 $ 绑定指示器,我不会收到任何错误,但文本和颜色不会更新。如何在不使代码过于复杂的情况下解决 SwiftUI 2 中的这些问题?

更新:

以上代码有效,但如果 text/color 更改是在从父视图调用的方法中完成的,则它不起作用,例如:

    func onAppear() {
    }

    // Called from parent view.
    func updateStrengthIndication() {
       segmentColor = Color.red
       hintText = "Enter password!"
    }

好的,另一种方法是为您的 PasswordStrengthIndicator 视图创建一个额外的视图模型,然后您可以将其包装在父视图的视图模型中。

// MARK: - Parent View
class ParentViewModel: ObservableObject {
    @Published var childViewModel = PasswordStrengthIndicatorViewModel()
 
    func updateBtnDidTab() {
        childViewModel.updateIndicator()
    }
}

struct ContentView: View {
    @StateObject var parentVM = ParentViewModel()
    
    var body: some View {
        VStack {
            PasswordStrengthIndicator(
                viewModel: parentVM.childViewModel
            )
            
            Button("Change", action: parentVM.updateBtnDidTab)
        }
        
    }
}

// MARK: - Child View
class PasswordStrengthIndicatorViewModel: ObservableObject {
    @Published private(set) var segmentColor = Color.gray
    @Published private(set) var hintText = ""
    
    func updateIndicator() {
        segmentColor = Color.green
        hintText = "asdf"
    }
}

struct PasswordStrengthIndicator: View {
    @ObservedObject var viewModel: PasswordStrengthIndicatorViewModel
    
    private let segment = RoundedRectangle(cornerRadius: CGFloat(4))

    var body: some View {
       VStack {
           segment
               .foregroundColor(viewModel.segmentColor)
           Text(viewModel.hintText)
       }
    }
}

编辑:
显示 PasswordStrengthIndicatorViewModel 的预览:

struct PasswordStrengthIndicator_Previews: PreviewProvider {
    static var previews: some View {
        PasswordStrengthIndicator(
            viewModel: PasswordStrengthIndicatorViewModel()
        )
    }
}