gpt4 book ai didi

swift - 是否可以在 SwiftUI 中向 TextField 添加字距调整?

转载 作者:行者123 更新时间:2023-12-04 13:17:34 27 4
gpt4 key购买 nike

为了匹配样式指南,我必须向文本字段添加字距调整,包括占位符和值本身。

使用 UIKit 我能够做到这一点:

    class MyTextField: UITextField {
override func awakeFromNib() {
super.awakeFromNib()

// ...

self.attributedPlaceholder = NSAttributedString(string: self.placeholder ?? "", attributes: [
//...
NSAttributedString.Key.kern: 0.3
])

self.attributedText = NSAttributedString(string: "", attributes: [
// ...
NSAttributedString.Key.kern: 0.3
])
}
}

在 SwiftUI 中,我发现可以对 Text 应用字距调整效果。像这样的元素:

    Text("My label with kerning")
.kerning(0.7)

不幸的是,我找不到将字距调整样式应用于 TextField 的值和占位符的方法。关于这个有什么想法吗?提前致谢

最佳答案

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 的包装版本这允许我们访问委托(delegate)方法。
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每次文本更改时都会调用委托(delegate)方法,我们应该使用它来更新 attributedText值(value)。我尝试先使用 proposedVale但它会使字符加倍,如果我们使用 currentValue,它会按预期工作

现在我们可以使用 WrappedTextFieldUIViewRepresentable .
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
}
}
}

关于swift - 是否可以在 SwiftUI 中向 TextField 添加字距调整?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58714303/

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