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
}
}
}
5条答案
按热度按时间vs91vp4v1#
iOS 15
您可以使用一个名为:
submitLabel
的简单修饰符来更改每个textField
的返回键,该修饰符采用返回键类型:图片来自WWDC21
此外,正如您所看到的,您可以有一个回调来处理回车键按下操作,就像旧的
textFieldShouldReturn
函数一样,可以通过.onSubmit
修饰符访问。️Xcode 13 beta 1上似乎有一个bug,阻止此修改器在某些情况下工作。
wfauudbj2#
更新
现在有一个更好的解决方案。在iOS 15中,您现在可以添加
.submitLabel(.done)
修改器。请参阅Mojtaba的回答以了解更多细节。旧答案
我发现的最好的方法是将包Introspect添加到项目中。
然后在项目文件的任何地方添加
import Introspect
。然后添加一个他们的视图修改器到你的
Textfield
来实现你想要的。字符串
Introspect是做什么的?
它公开了在SwiftUI中使用的UIKit。所以你在上面看到的
Textfield
对象可以访问UITextfield
的所有功能!这是一个包,所以要注意它可能会在未来崩溃,但现在这是一个很好的选择。这很好,因为它让你不必为每个视图制作自己的UIKit Package 器。
j8ag8udp3#
要获取键盘上的
go
按钮,请尝试将keyboardtype更改为. webSearch。//在Xcode 12 beta 2和iOS 14上测试
.keyboardType(.webSearch)
vecaoik14#
如果有人正在寻找在UIViewRepresentable中 Package EifextField,那么我有一些代码可以分享:
字符串
rryofs0p5#
iOS 15.0+
macOS 12.0+、Mac Catalyst 15.0+、tvOS 15.0+、watchOS 8.0+
第一个月
设置此视图的提交标签。
https://developer.apple.com
字符串