在HackingwithSwift上有一个简单的教程,显示了如何实现UITextView。可以很容易地将其修改为UITextField。
这是一个简单的示例,显示了如何UIViewRepresentable
为您使用UITextField
。在文本和占位符上设置字距调整。
struct ContentView: View {
@State var text = ""
var body: some View {
MyTextField(text: $text,placeholder: "Placeholder")
}
}
struct MyTextField: UIViewRepresentable {
@Binding var text: String
var placeholder: String
func makeUIView(context: Context) -> UITextField {
return UITextField()
}
func updateUIView(_ uiView: UITextField,context: Context) {
uiView.attributedPlaceholder = NSAttributedString(string: self.placeholder,attributes: [
NSAttributedString.Key.kern: 0.3
])
uiView.attributedText = NSAttributedString(string: self.text,attributes: [
NSAttributedString.Key.kern: 0.3
])
}
}
更新
以上内容不适用于对attributedText设置字距调整。借用Costantino Pistagna在他的medium article中所做的出色工作,我们需要做更多的工作。
首先,我们需要创建UITextField
的包装版本,以允许我们访问委托方法。
class WrappableTextField: UITextField,UITextFieldDelegate {
var textFieldChangedHandler: ((String)->Void)?
var onCommitHandler: (()->Void)?
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
if let nextField = textField.superview?.superview?.viewWithTag(textField.tag + 1) as? UITextField {
nextField.becomeFirstResponder()
} else {
textField.resignFirstResponder()
}
return false
}
func textField(_ textField: UITextField,shouldChangeCharactersIn range: NSRange,replacementString string: String) -> Bool {
if let currentValue = textField.text as NSString? {
let proposedValue = currentValue.replacingCharacters(in: range,with: string)
print(proposedValue)
self.attributedText = NSAttributedString(string: currentValue as String,attributes: [
NSAttributedString.Key.kern: 10
])
textFieldChangedHandler?(proposedValue as String)
}
return true
}
func textFieldDidEndEditing(_ textField: UITextField) {
onCommitHandler?()
}
}
由于每次文本更改时都会调用shouldChangeCharactersIn
委托方法,因此我们应该使用该方法来更新attributedText
的值。我尝试先使用proposedVale
,但是它将字符加倍,如果我们使用currentValue
,它可以按预期工作
现在我们可以在WrappedTextField
中使用UIViewRepresentable
。
struct SATextField: UIViewRepresentable {
private let tmpView = WrappableTextField()
//var exposed to SwiftUI object init
var tag:Int = 0
var placeholder:String?
var changeHandler:((String)->Void)?
var onCommitHandler:(()->Void)?
func makeUIView(context: UIViewRepresentableContext<SATextField>) -> WrappableTextField {
tmpView.tag = tag
tmpView.delegate = tmpView
tmpView.placeholder = placeholder
tmpView.attributedPlaceholder = NSAttributedString(string: self.placeholder ?? "",attributes: [
NSAttributedString.Key.kern: 10
])
tmpView.onCommitHandler = onCommitHandler
tmpView.textFieldChangedHandler = changeHandler
return tmpView
}
func updateUIView(_ uiView: WrappableTextField,context: UIViewRepresentableContext<SATextField>) {
uiView.setContentHuggingPriority(.defaultHigh,for: .vertical)
uiView.setContentHuggingPriority(.defaultLow,for: .horizontal)
}
}
我们在makeUIView
中设置占位符的属性文本。占位符文本未更新,因此我们不必担心更改它。
这是我们的用法:
struct ContentView: View {
@State var text = ""
var body: some View {
SATextField(tag: 0,placeholder: "Placeholder",changeHandler: { (newText) in
self.text = newText
}) {
// do something when the editing of this textfield ends
}
}
}
本文链接:https://www.f2er.com/3158478.html