使字符串和颜色可绑定
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()
)
}
}
我有一些类似下面的代码,我想通过 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()
)
}
}