我如何通过iPhone键盘上的“下一步”按钮浏览所有的文本字段?
最后一个文本字段应该关闭键盘。
我已经设置了IB按钮(下一步/完成),但现在我卡住了。
我实现了textFieldShouldReturn动作,但现在下一步和完成按钮关闭键盘。
我如何通过iPhone键盘上的“下一步”按钮浏览所有的文本字段?
最后一个文本字段应该关闭键盘。
我已经设置了IB按钮(下一步/完成),但现在我卡住了。
我实现了textFieldShouldReturn动作,但现在下一步和完成按钮关闭键盘。
当前回答
一种更安全、更直接的方式,假设:
文本字段委托被设置为你的视图控制器 所有文本字段都是同一视图的子视图 文本字段的标签按照你想要进行的顺序(例如,textField2. txt)。标签= 2,textField3。Tag = 3,等等) 当你点击键盘上的返回按钮时,就会移动到下一个文本字段(你可以将此更改为next, done等)。 您希望键盘在最后一个文本字段之后被取消
斯威夫特4.1:
extension ViewController: UITextFieldDelegate {
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
let nextTag = textField.tag + 1
guard let nextTextField = textField.superview?.viewWithTag(nextTag) else {
textField.resignFirstResponder()
return false
}
nextTextField.becomeFirstResponder()
return false
}
}
其他回答
没有usings标签,也没有为nextField/nextTextField添加属性,你可以尝试模拟TAB,其中"testInput"是你当前的活动字段:
if ([textInput isFirstResponder])
[textInput.superview.subviews enumerateObjectsAtIndexes:
[NSIndexSet indexSetWithIndexesInRange:
NSMakeRange([textInput.superview.subviews indexOfObject:textInput]+1,
[textInput.superview.subviews count]-[textInput.superview.subviews indexOfObject:textInput]-1)]
options:0 usingBlock:^(UIView *obj, NSUInteger idx, BOOL *stop) {
*stop = !obj.hidden && [obj becomeFirstResponder];
}];
if ([textInput isFirstResponder])
[textInput.superview.subviews enumerateObjectsAtIndexes:
[NSIndexSet indexSetWithIndexesInRange:
NSMakeRange(0,
[textInput.superview.subviews indexOfObject:textInput])]
options:0 usingBlock:^(UIView *obj, NSUInteger idx, BOOL *stop) {
*stop = !obj.hidden && [obj becomeFirstResponder];
}];
在textFieldShouldReturn你应该检查你目前的文本域不是最后一个,当他们点击下一步,如果不是不要解散键盘..
解决方案在Swift 3.1,连接你的文本字段IBOutlets设置你的文本字段委托在viewDidLoad,然后在textFieldShouldReturn导航你的动作
class YourViewController: UIViewController,UITextFieldDelegate {
@IBOutlet weak var passwordTextField: UITextField!
@IBOutlet weak var phoneTextField: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
self.passwordTextField.delegate = self
self.phoneTextField.delegate = self
// Set your return type
self.phoneTextField.returnKeyType = .next
self.passwordTextField.returnKeyType = .done
}
func textFieldShouldReturn(_ textField: UITextField) -> Bool{
if textField == self.phoneTextField {
self.passwordTextField.becomeFirstResponder()
}else if textField == self.passwordTextField{
// Call login api
self.login()
}
return true
}
}
我很惊讶,这里有这么多答案没有理解一个简单的概念:在应用程序中的控件中导航不是视图本身应该做的事情。控制器的工作是决定将哪个控件作为下一个第一响应器。
此外,大多数答案只适用于前进导航,但用户也可能想后退。
这就是我想到的。表单应该由视图控制器管理,视图控制器是响应器链的一部分。所以你可以完全自由地实现以下方法:
#pragma mark - Key Commands
- (NSArray *)keyCommands
{
static NSArray *commands;
static dispatch_once_t once;
dispatch_once(&once, ^{
UIKeyCommand *const forward = [UIKeyCommand keyCommandWithInput:@"\t" modifierFlags:0 action:@selector(tabForward:)];
UIKeyCommand *const backward = [UIKeyCommand keyCommandWithInput:@"\t" modifierFlags:UIKeyModifierShift action:@selector(tabBackward:)];
commands = @[forward, backward];
});
return commands;
}
- (void)tabForward:(UIKeyCommand *)command
{
NSArray *const controls = self.controls;
UIResponder *firstResponder = nil;
for (UIResponder *const responder in controls) {
if (firstResponder != nil && responder.canBecomeFirstResponder) {
[responder becomeFirstResponder]; return;
}
else if (responder.isFirstResponder) {
firstResponder = responder;
}
}
[controls.firstObject becomeFirstResponder];
}
- (void)tabBackward:(UIKeyCommand *)command
{
NSArray *const controls = self.controls;
UIResponder *firstResponder = nil;
for (UIResponder *const responder in controls.reverseObjectEnumerator) {
if (firstResponder != nil && responder.canBecomeFirstResponder) {
[responder becomeFirstResponder]; return;
}
else if (responder.isFirstResponder) {
firstResponder = responder;
}
}
[controls.lastObject becomeFirstResponder];
}
额外的逻辑滚动屏幕外的响应可见之前可能适用。
这种方法的另一个优点是,您不需要子类化您可能想要显示的所有类型的控件(如UITextFields),而是可以在控制器级别管理逻辑,老实说,在控制器级别管理逻辑是正确的。
如果有人想这样。我认为这是最接近问题所要求的要求
下面是我如何实现它
为需要设置的每个文本字段添加附件视图,使用
func setAccessoryViewFor(textField : UITextField) {
let toolBar = UIToolbar()
toolBar.barStyle = .default
toolBar.isTranslucent = true
toolBar.sizeToFit()
// Adds the buttons
// Add previousButton
let prevButton = UIBarButtonItem(title: "<", style: .plain, target: self, action: #selector(previousPressed(sender:)))
prevButton.tag = textField.tag
if getPreviousResponderFor(tag: textField.tag) == nil {
prevButton.isEnabled = false
}
// Add nextButton
let nextButton = UIBarButtonItem(title: ">", style: .plain, target: self, action: #selector(nextPressed(sender:)))
nextButton.tag = textField.tag
if getNextResponderFor(tag: textField.tag) == nil {
nextButton.title = "Done"
}
let spaceButton = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
toolBar.setItems([prevButton,spaceButton,nextButton], animated: false)
toolBar.isUserInteractionEnabled = true
textField.inputAccessoryView = toolBar
}
使用以下函数来处理轻拍
func nextPressed(sender : UIBarButtonItem) {
if let nextResponder = getNextResponderFor(tag: sender.tag) {
nextResponder.becomeFirstResponder()
} else {
self.view.endEditing(true)
}
}
func previousPressed(sender : UIBarButtonItem) {
if let previousResponder = getPreviousResponderFor(tag : sender.tag) {
previousResponder.becomeFirstResponder()
}
}
func getNextResponderFor(tag : Int) -> UITextField? {
return self.view.viewWithTag(tag + 1) as? UITextField
}
func getPreviousResponderFor(tag : Int) -> UITextField? {
return self.view.viewWithTag(tag - 1) as? UITextField
}
您需要按您希望下一个/前一按钮响应的顺序给出textFields标记。