gpt4 book ai didi

uikit - SwiftUI 通过实现 UIViewRepresentable 使用 UIKit 组件

转载 作者:行者123 更新时间:2023-12-02 07:09:57 64 4
gpt4 key购买 nike

好的,我知道如何使用 UIViewRepresentable 和 Coordinator 包装像 TextField 这样的 UIKit 组件,以便与 SwiftUI 一起使用。一切都运转良好。但是,我如何以 SwiftUI 原生的方式(即使用修饰符)从 SwiftUI 角度自定义此组件?

我有 UITextField 的示例包装器,可以启用一些额外的委托(delegate)方法处理。这与将闭包传递给构造函数的 native 方法类似。但是我如何使用 SwiftUI 修饰符对此 UITextField 应用一些样式?

struct PasswordField: UIViewRepresentable {

@Binding var text: String
@Binding var isSecured: Bool

let onBeginEditing: () -> Void
let onEndEditing: () -> Void
let onEditingChanged: (Bool) -> Void
let onCommit: () -> Void


init(text: Binding<String>, isSecured : Binding<Bool> = .constant(true),
onBeginEditing: @escaping () -> Void = { },
onEndEditing: @escaping () -> Void = { },
onEditingChanged: @escaping (Bool) -> Void = { _ in },
onCommit: @escaping () -> Void = { }) {

self._text = text
self._isSecured = isSecured
self.onBeginEditing = onBeginEditing
self.onEndEditing = onEndEditing
self.onEditingChanged = onEditingChanged
self.onCommit = onCommit
}

func makeCoordinator() -> Coordinator {
Coordinator(onBeginEditing: onBeginEditing, onEndEditing: onEndEditing, onEditingChanged: onEditingChanged, onCommit: onCommit)
}

func makeUIView(context: UIViewRepresentableContext<PasswordField>) -> UITextField {

let textField = UITextField()
textField.delegate = context.coordinator
textField.addTarget(context, action: #selector(Coordinator.valueChanged(sender:)), for: .valueChanged)
return textField
}

func updateUIView(_ uiView: UITextField, context: UIViewRepresentableContext<PasswordField>) {

uiView.text = text
uiView.isSecureTextEntry = isSecured
}
}

// MARK: - Coordinator
extension PasswordField {

class Coordinator: NSObject, UITextFieldDelegate {

let onBeginEditing: () -> Void
let onEndEditing: () -> Void
let onEditingChanged: (Bool) -> Void
let onCommit: () -> Void

init(onBeginEditing: @escaping () -> Void,
onEndEditing: @escaping () -> Void,
onEditingChanged: @escaping (Bool) -> Void,
onCommit: @escaping () -> Void) {
self.onBeginEditing = onBeginEditing
self.onEndEditing = onEndEditing
self.onEditingChanged = onEditingChanged
self.onCommit = onCommit
}

@objc func valueChanged(sender: UITextField) {
onEditingChanged(true)
}

func textFieldShouldReturn(_ textField: UITextField) -> Bool {
textField.resignFirstResponder()
onCommit()
return true
}

func textFieldDidBeginEditing(_ textField: UITextField) {
onBeginEditing()
onEditingChanged(true)
}

func textFieldDidEndEditing(_ textField: UITextField) {
onEditingChanged(false)
onEndEditing()
}
}
}

struct PasswordField_Previews: PreviewProvider {
static var previews: some View {
PasswordField(text: .constant("PaSSword"), isSecured: .constant(true))
}
}

现在我想像这样使用它:

PasswordField(text: self.$validator.value, onEditingChanged: { editing in
self.onEditingChanged?(editing)
self.isEdited = true
}, onCommit: {
self.validator.validateField()
self.validator.validateFieldAsync()
})
.font(.custom("AvenirNext-Light", size: 13)) // THIS IS IMPORTANT
.foregroundColor(Color("BodyText")) // THIS IS IMPORTANT
.frame(maxHeight: geometry.size.height)
.offset(x: 0, y: 16)
.padding(10)

好的,我知道我可以在包装器中硬编码这种样式,或者通过构造函数传递它。是的,但这不是 SwiftUI 本身的做法。

最佳答案

您需要实现自己的自定义修饰符。请参阅 ViewModifier 协议(protocol)的文档,尽管 SwiftUI 文档仍然很薄。

但是,您不必实现自己的 TextField 来处理密码输入,因为 SwiftUI 现在原生支持您想要的内容:SecureField。

关于uikit - SwiftUI 通过实现 UIViewRepresentable 使用 UIKit 组件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59370964/

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