gpt4 book ai didi

ios - 如何将 ObservableObject 与 UIViewRepresentable 一起使用

转载 作者:行者123 更新时间:2023-11-28 07:20:54 24 4
gpt4 key购买 nike

我正在使用 MVVM 构建一个 SwiftUI 应用。

我需要一些额外的文本字段行为,所以我将 UITextField 包装在 UIViewRepresentable View 中。

如果我在包含我的文本字段的 View 中使用简单的 @State 来绑定(bind)文本,自定义文本字段将按预期运行;但是因为我想在 View 模型中存储我的文本字段的所有文本,所以我使用了 @ObservedObject;使用它时,文本字段绑定(bind)不起作用:它看起来总是重置为初始状态(空文本)并且它不发布任何值(并且 View 不刷新)。这种奇怪的行为只发生在 UIViewRepresentable View 中。

我的主视图包含一个表单,它看起来像这样:

struct LoginSceneView: View {

@ObservedObject private var viewModel: LoginViewModel = LoginViewModel()

var body: some View {
ScrollView(showsIndicators: false) {
VStack(spacing: 22) {
UIKitTextField(text: $viewModel.email, isFirstResponder: $viewModel.isFirstResponder)
SecureField("Password", text: $viewModel.password)
Button(action: {}) {
Text("LOGIN")
}
.disabled(!viewModel.isButtonEnabled)
}
.padding(.vertical, 40)
}
}

}

View 模型是这样的:

class LoginViewModel: ObservableObject {

@Published var email = ""
@Published var password = ""
@Published var isFirstResponder = false

var isButtonEnabled: Bool { !email.isEmpty && !password.isEmpty }

}

最后,这是我的自定义文本字段:

struct UIKitTextField: UIViewRepresentable {

// MARK: - Coordinator

class Coordinator: NSObject, UITextFieldDelegate {

private let textField: UIKitTextField

fileprivate init(_ textField: UIKitTextField) {
self.textField = textField

super.init()
}

@objc fileprivate func editingChanged(_ sender: UITextField) {
let text = sender.text ?? ""
textField.text = text
textField.onEditingChanged(text)
}

func textFieldDidBeginEditing(_ textField: UITextField) {
self.textField.onEditingBegin()
}

func textFieldDidEndEditing(_ textField: UITextField) {
self.textField.onEditingEnd()
}

func textFieldShouldReturn(_ textField: UITextField) -> Bool {
self.textField.onReturnKeyPressed()
}

}

// MARK: - Properties

@Binding private var text: String
private let onEditingChanged: (String) -> Void
private let onEditingBegin: () -> Void
private let onEditingEnd: () -> Void
private let onReturnKeyPressed: () -> Bool

// MARK: - Initializers

init(text: Binding<String>,
onEditingChanged: @escaping (String) -> Void = { _ in },
onEditingBegin: @escaping () -> Void = {},
onEditingEnd: @escaping () -> Void = {},
onReturnKeyPressed: @escaping () -> Bool = { true }) {
_text = text
self.onEditingChanged = onEditingChanged
self.onEditingBegin = onEditingBegin
self.onEditingEnd = onEditingEnd
self.onReturnKeyPressed = onReturnKeyPressed
}

// MARK: - UIViewRepresentable methods

func makeCoordinator() -> Coordinator { Coordinator(self) }

func makeUIView(context: Context) -> UITextField {
let textField = UITextField()
textField.delegate = context.coordinator
textField.setContentHuggingPriority(.defaultHigh, for: .vertical)
textField.addTarget(context.coordinator, action: #selector(Coordinator.editingChanged(_:)), for: .editingChanged)
return textField
}

func updateUIView(_ uiView: UITextField, context: Context) {
uiView.text = text
}

}

最佳答案

您的问题可能是每次更改某些绑定(bind)变量时都会创建 UIViewRepresentable。放入调试代码进行检查。

struct UIKitTextField: UIViewRepresentable {
init() {
print("UIViewRepresentable init()")
}
...
}

关于ios - 如何将 ObservableObject 与 UIViewRepresentable 一起使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58099025/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com