在 SwiftUI 中为 TextField 打开键盘时,我没有找到任何将“返回”键更改为“完成”的链接或指南。
现在可以不自定义 UITextField 吗?
Moj*_*ini 13
您可以textField使用一个简单的修饰符为每个更改返回键:调用submitLabel返回键类型:
此外,如您所见,您可以使用回调来处理返回键按下操作,就像修饰符textFieldShouldReturn可访问的旧函数一样.onSubmit。
?? 似乎 Xcode 13 beta 1 上存在一个错误,该错误会阻止此修饰符在某些情况下工作。
tyi*_*ine 11
这不再是一个好的解决方案。在 iOS 15 中,您现在可以添加.submitLabel(.done)修饰符。有关更多详细信息,请参阅 Mojtaba 的回答。
我发现的最好方法是将Introspect包添加到您的项目中。
这样做之后,import Introspect在项目文件的任何地方添加。
然后将他们的视图修改器之一添加到您的中Textfield以实现您想要的。我相信这就是你想要的吗?
.introspectTextField { textfield in
textfield.returnKeyType = .done
}
Run Code Online (Sandbox Code Playgroud)
它公开了要在 SwiftUI 中使用的 UIKit。因此,Textfield您在上面看到的对象可以访问所有UITextfield功能!这是一个包,所以请注意它将来可能会损坏,但现在这是一个不错的选择。
这很好,因为它使您无需为每个视图制作自己的 UIKit 包装器
如果有人正在寻找将 UITextField 包装在 UIViewRepresentable 中,那么我有一些代码要分享:
struct CustomTextField: UIViewRepresentable {
let tag: Int
let placeholder: String
let keyboardType: UIKeyboardType
let returnVal: UIReturnKeyType
@Binding var text: String
@Binding var activeFieldTag: Int?
var totalFields: Int = 0
@Binding var isSecureTextEntry: Bool
var textColor: UIColor = .pureWhite
var font: UIFont = .nexaBold13
var placeholderTextColor: UIColor = .pureWhite
var placeholderFont: UIFont = .nexaLight13
var onEditingChanged: (Bool) -> Void = { _ in }
var lastActiveFieldTag: Int? {
// Return, if no active field
// (It also means textFieldShouldReturn not called yet OR called for last field)
guard let activeFieldTag = activeFieldTag else {
return nil
}
// Return previous field
if activeFieldTag > 0 {
return activeFieldTag - 1
}
// Return, if no previous field
return nil
}
func makeUIView(context: Context) -> UITextField {
let textField = UITextField(frame: .zero)
textField.keyboardType = self.keyboardType
textField.returnKeyType = self.returnVal
textField.tag = self.tag
textField.textColor = textColor
textField.font = font
textField.attributedPlaceholder = NSAttributedString(
string: self.placeholder,
attributes: [
NSAttributedString.Key.foregroundColor: placeholderTextColor,
NSAttributedString.Key.font: placeholderFont,
]
)
textField.delegate = context.coordinator
textField.autocorrectionType = .no
textField.isSecureTextEntry = isSecureTextEntry
return textField
}
func updateUIView(_ textField: UITextField, context: Context) {
if textField.text != self.text {
textField.text = self.text
}
handleFirstResponder(textField)
if textField.isSecureTextEntry != isSecureTextEntry {
textField.isSecureTextEntry = isSecureTextEntry
}
}
func handleFirstResponder(_ textField: UITextField) {
// return if field is neither active nor last-active
if tag != lastActiveFieldTag && tag != activeFieldTag {
return
}
// return if field is already active
if lastActiveFieldTag == activeFieldTag {
return
}
// It creates problem in UI when we press the next button too fast and continuously on keyboard
// // Remove focus from last active field
// if lastActiveFieldTag == tag {
// uiView.removeFocus()
// return
// }
// Give focus to active field
if activeFieldTag == tag {
textField.focus()
return
}
}
// Its called when pressing Next button on the keyboard
// See textFieldShouldReturn
func updateNextTag() {
// There is no next field so set activeFieldTag to nil
if tag + 1 == totalFields {
activeFieldTag = nil
} else {
// Set next field tag as active
activeFieldTag = tag + 1
}
}
func makeCoordinator() -> Coordinator {
Coordinator(self)
}
class Coordinator: NSObject, UITextFieldDelegate {
var parent: CustomTextField
init(_ textField: CustomTextField) {
self.parent = textField
}
func updatefocus(textfield: UITextField) {
textfield.focus()
}
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
// Give focus to next field
parent.updateNextTag()
parent.text = textField.text ?? ""
// If there is no next active field then dismiss the keyboard
if parent.activeFieldTag == nil {
DispatchQueue.main.async {
textField.removeFocus()
}
}
return true
}
func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
DispatchQueue.main.async {
// To enable user to click on any textField while another is active
self.parent.activeFieldTag = self.parent.tag
self.parent.onEditingChanged(true)
}
return true
}
func textFieldShouldEndEditing(_ textField: UITextField) -> Bool {
self.parent.text = textField.text ?? ""
DispatchQueue.main.async {
self.parent.onEditingChanged(false)
}
return true
}
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
if let text = textField.text, let rangeExp = Range(range, in: text) {
self.parent.text = text.replacingCharacters(in: rangeExp, with: string)
}
return true
}
}
}
Run Code Online (Sandbox Code Playgroud)
macOS 12.0+、Mac Catalyst 15.0+、tvOS 15.0+、watchOS 8.0+
submitLabel(_:)设置此视图的提交标签。
Form {
TextField("Username", $viewModel.username)
.submitLabel(.done)
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
8231 次 |
| 最近记录: |