如何使用iPhone键盘上的“下一步”按钮浏览所有文本字段?

最后一个文本字段应该关闭键盘。

我已经设置了IB按钮(下一个/完成),但现在我被卡住了。

我实现了textFieldShouldReturn操作,但现在Next和Done Buttons关闭了Keyboard。


#1楼

我喜欢Anth0和Answerbot已经提出过的OO解决方案。 但是,我正在开发一个快速小巧的POC,所以我不想让子类和类别混乱。

另一个简单的解决方案是创建一个NSArray字段,并在按下下一个字段时查找下一个字段。 不是OO解决方案,但快速,简单且易于实施。 此外,您可以一目了然地查看和修改订购。

这是我的代码(基于此线程中的其他答案):

@property (nonatomic) NSArray *fieldArray;- (void)viewDidLoad {[super viewDidLoad];fieldArray = [NSArray arrayWithObjects: firstField, secondField, thirdField, nil];
}- (BOOL) textFieldShouldReturn:(UITextField *) textField {BOOL didResign = [textField resignFirstResponder];if (!didResign) return NO;NSUInteger index = [self.fieldArray indexOfObject:textField];if (index == NSNotFound || index + 1 == fieldArray.count) return NO;id nextField = [fieldArray objectAtIndex:index + 1];activeField = nextField;[nextField becomeFirstResponder];return NO;
}
  • 我总是返回NO,因为我不想插入换行符。 我以为我会指出这一点,因为当我返回YES时它将自动退出后续字段或在我的TextView中插入换行符。 我花了一点时间才弄明白。
  • activeField会跟踪活动字段,以防需要滚动来从键盘中取消显示字段。 如果您有类似的代码,请确保在更改第一个响应者之前分配activeField。 立即更改第一响应者并立即触发KeyboardWasShown事件。

#2楼

我已经添加了PeyloW的答案,以防你想要实现上一个/下一个按钮功能:

- (IBAction)moveThroughTextFields:(UIBarButtonItem *)sender
{NSInteger nextTag;UITextView *currentTextField = [self.view findFirstResponderAndReturn];if (currentTextField != nil) {// I assigned tags to the buttons.  0 represent prev & 1 represents nextif (sender.tag == 0) {nextTag = currentTextField.tag - 1;} else if (sender.tag == 1) {nextTag = currentTextField.tag + 1;}}// Try to find next responderUIResponder* nextResponder = [self.view viewWithTag:nextTag];if (nextResponder) {// Found next responder, so set it.// I added the resign here in case there's different keyboards in place.[currentTextField resignFirstResponder];[nextResponder becomeFirstResponder];} else {// Not found, so remove keyboard.[currentTextField resignFirstResponder];}
}

你把UIView子类化的地方是这样的:

@implementation UIView (FindAndReturnFirstResponder)
- (UITextView *)findFirstResponderAndReturn
{for (UITextView *subView in self.subviews) {if (subView.isFirstResponder){return subView;}}return nil;
}
@end

#3楼

 -(BOOL)textFieldShouldReturn:(UITextField *)textField
{[[self.view viewWithTag:textField.tag+1] becomeFirstResponder];return YES;
}

#4楼

在textFieldShouldReturn中,你应该检查你当前所在的文本字段是不是最后一个,当他们点击下一个,如果它不要关闭键盘..


#5楼

退出一个文本字段后,调用[otherTextField becomeFirstResponder],下一个字段获得焦点。

这实际上可能是一个棘手的问题,因为您通常还需要滚动屏幕或以其他方式调整文本字段的位置,以便在编辑时很容易看到。 只需确保以不同的方式进出文本字段并进行大量测试,并提前离开(总是让用户选择关闭键盘而不是去下一个字段,通常使用“完成”导航栏)


#6楼

在Cocoa for Mac OS X中,您有下一个响应者链,您可以在其中询问文本字段接下来应该关注哪个控件。 这就是使文本字段之间的标签工作的原因。 但由于iOS设备没有键盘,只有触摸,这个概念还没有幸免于过渡到Cocoa Touch。

无论如何,这可以轻松完成,有两个假设:

  1. 所有“tabbable” UITextField都在同一父视图上。
  2. 他们的“tab-order”由tag属性定义。

假设你可以覆盖textFieldShouldReturn:如下:

-(BOOL)textFieldShouldReturn:(UITextField*)textField
{NSInteger nextTag = textField.tag + 1;// Try to find next responderUIResponder* nextResponder = [textField.superview viewWithTag:nextTag];if (nextResponder) {// Found next responder, so set it.[nextResponder becomeFirstResponder];} else {// Not found, so remove keyboard.[textField resignFirstResponder];}return NO; // We do not want UITextField to insert line-breaks.
}

添加更多代码,也可以忽略这些假设。

Swift 4.0

 func textFieldShouldReturn(_ textField: UITextField) -> Bool {let nextTag = textField.tag + 1// Try to find next responderlet nextResponder = textField.superview?.viewWithTag(nextTag) as UIResponder!if nextResponder != nil {// Found next responder, so set itnextResponder?.becomeFirstResponder()} else {// Not found, so remove keyboardtextField.resignFirstResponder()}return false
}

如果文本字段的超级视图将是UITableViewCell,则下一个响应者将是

let nextResponder = textField.superview?.superview?.superview?.viewWithTag(nextTag) as UIResponder!

#7楼

我尝试使用更复杂的方法来解决这个问题,该方法基于在UITableView为每个单元格(或UITextField )分配一个可以在以后检索的唯一标记值: activate-next-uitextfield-in-uitableview-ios

我希望这有帮助!


#8楼

我更喜欢:

@interface MyViewController : UIViewController
@property (nonatomic, retain) IBOutletCollection(UIView) NSArray *inputFields;
@end

在NIB文件中,我将textFields以所需顺序挂钩到此inputFields数组中。 之后,我对UITextField的索引进行了简单测试,该索引报告用户点击了返回:

// for UITextField
-(BOOL)textFieldShouldReturn:(UITextField*)textField {NSUInteger index = [_inputFields indexOfObject:textField];index++;if (index < _inputFields.count) {UIView *v = [_inputFields objectAtIndex:index];[v becomeFirstResponder];}return NO;
}// for UITextView
-(BOOL)textView:(UITextView*)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString*)text {if ([@"\n" isEqualToString:text]) {NSUInteger index = [_inputFields indexOfObject:textView];index++;if (index < _inputFields.count) {UIView *v = [_inputFields objectAtIndex:index];[v becomeFirstResponder];} else {[self.view endEditing:YES];}return NO;}return YES;
}

#9楼

首先在xib中设置键盘返回键,否则你可以在viewdidload编写代码:

passWord.returnKeyType = UIReturnKeyNext;-(BOOL)textFieldShouldReturn:(UITextField *)textField
{if(textField == eMail) {[textField resignFirstResponder];[userName becomeFirstResponder];}if (textField==userName) {[textField resignFirstResponder];[passWord becomeFirstResponder];}if (textField==passWord) {[textField resignFirstResponder];[country becomeFirstResponder];}if (textField==country) {[textField resignFirstResponder];}return YES;
}

#10楼

这是一个没有代表团的人:

tf1.addTarget(tf2, action: #selector(becomeFirstResponder), for: .editingDidEndOnExit)
tf2.addTarget(tf3, action: #selector(becomeFirstResponder), for: .editingDidEndOnExit)

ObjC:

[tf1 addTarget:tf2 action:@selector(becomeFirstResponder) forControlEvents:UIControlEventEditingDidEndOnExit];
[tf2 addTarget:tf3 action:@selector(becomeFirstResponder) forControlEvents:UIControlEventEditingDidEndOnExit];

使用(大多数未知的) UIControlEventEditingDidEndOnExit UITextField操作。

您还可以轻松地将其连接到故事板中,因此不需要委托代码。

编辑:实际上我无法弄清楚如何在故事板中将其连接起来。 对于这个控件事件,似乎并不是一个有效的第一个becomeFirstResponder者,这很可惜。 仍然,您可以将所有文本字段挂钩到ViewController中的单个操作,然后根据发件人确定哪个textField成为becomeFirstResponder (尽管它不像上面的编程解决方案那样优雅,所以IMO使用viewDidLoad的上述代码执行它)。


#11楼

这是使用UIControl上的类别进行Tab键的实现。 这个解决方案具有Michael和Anth0方法的所有优点,但适用于所有UIControl,而不仅仅是UITextField 。 它还可以与Interface Builder和故事板无缝协作。

源和示例应用程序: UIControlsWithTabbing的GitHub存储库

用法:

- (BOOL)textFieldShouldReturn:(UITextField *)textField
{[textField transferFirstResponderToNextControl];return NO;
}

标题:

//
// UIControl+NextControl.h
// UIControlsWithTabbing
//#import <UIKit/UIKit.h>@interface UIControl (NextControl)@property (nonatomic, weak) IBOutlet UIControl *nextControl;- (BOOL)transferFirstResponderToNextControl;@end

执行:

#import "UIControl+NextControl.h"
#import <objc/runtime.h>static char defaultHashKey;@implementation UIControl (NextControl)- (UIControl *)nextControl
{return objc_getAssociatedObject(self, &defaultHashKey);
}- (void)setNextControl:(UIControl *)nextControl
{objc_setAssociatedObject(self, &defaultHashKey, nextControl, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}- (BOOL)transferFirstResponderToNextControl
{if (self.nextControl){[self.nextControl becomeFirstResponder];return YES;}[self resignFirstResponder];return NO;
}@end

#12楼

if (cell == nil)
{cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];txt_Input = [[ UITextField alloc] initWithFrame:CGRectMake(0, 10, 150, 30)];txt_Input.tag = indexPath.row+1;[self.array_Textfields addObject:txt_Input]; // Initialize mutable array in ViewDidLoad
}-(BOOL)textFieldShouldReturn:(UITextField *)textField
{int tag = ( int) textField.tag ;UITextField * txt = [  self.array_Textfields objectAtIndex:tag ] ;[ txt becomeFirstResponder] ;return YES ;
}

#13楼

我的故事板中有大约10多个UITextField,我启用下一个功能的方式是创建一个UITextField数组,并使下一个UITextField成为第一个响应者。 这是实现文件:

#import "RegistrationTableViewController.h"@interface RegistrationTableViewController ()
@property (weak, nonatomic) IBOutlet UITextField *fullNameTextField;
@property (weak, nonatomic) IBOutlet UITextField *addressTextField;
@property (weak, nonatomic) IBOutlet UITextField *address2TextField;
@property (weak, nonatomic) IBOutlet UITextField *cityTextField;
@property (weak, nonatomic) IBOutlet UITextField *zipCodeTextField;
@property (weak, nonatomic) IBOutlet UITextField *urlTextField;
@property (weak, nonatomic) IBOutlet UITextField *usernameTextField;
@property (weak, nonatomic) IBOutlet UITextField *emailTextField;
@property (weak, nonatomic) IBOutlet UITextField *passwordTextField;
@property (weak, nonatomic) IBOutlet UITextField *confirmPWTextField;@end
NSArray *uiTextFieldArray;
@implementation RegistrationTableViewController- (void)viewDidLoad {[super viewDidLoad];NSLog(@"view did load");uiTextFieldArray = @[self.fullNameTextField,self.addressTextField,self.address2TextField,self.cityTextField,self.zipCodeTextField,self.urlTextField,self.usernameTextField,self.emailTextField,self.passwordTextField,self.confirmPWTextField];for(UITextField *myField in uiTextFieldArray){myField.delegate = self;}}
-(BOOL)textFieldShouldReturn:(UITextField *)textField{long index = [uiTextFieldArray indexOfObject:textField];NSLog(@"%ld",index);if(index < (uiTextFieldArray.count - 1)){[uiTextFieldArray[++index] becomeFirstResponder];}else{[uiTextFieldArray[index] resignFirstResponder];}return YES;
}
- (void)didReceiveMemoryWarning {[super didReceiveMemoryWarning];// Dispose of any resources that can be recreated.
}@end

#14楼

这是一个老帖子,但页面排名很高,所以我会使用我的解决方案。

我遇到了类似的问题,最后创建了UIToolbar的子类来管理动态tableView中的下一个/上一个/完成的功能,其中包含以下部分: https : //github.com/jday001/DataEntryToolbar

将工具栏设置为文本字段的inputAccessoryView并将其添加到其字典中。 这使您可以向前和向后循环,即使是动态内容也是如此。 如果要在textField导航发生时触发自己的功能,则有委托方法,但您不必处理管理任何标记或第一响应者状态。

GitHub链接中有代码片段和示例应用程序,以帮助实现详细信息。 您将需要自己的数据模型来跟踪字段内的值。


#15楼

我一直在使用Michael G. Emmons的答案大约一年,效果很好。 我最近注意到,调用resignFirstResponder然后立即调用FirstFirstResponder会导致键盘“出现故障”,消失然后立即出现。 如果nextField可用,我稍微更改了他的版本以跳过resignFirstResponder。

- (BOOL)textFieldShouldReturn:(UITextField *)textField
{ if ([textField isKindOfClass:[NRTextField class]]){NRTextField *nText = (NRTextField*)textField;if ([nText nextField] != nil){dispatch_async(dispatch_get_main_queue(),^ { [[nText nextField] becomeFirstResponder]; });}else{[textField resignFirstResponder];}}else{[textField resignFirstResponder];}return true;}

#16楼

我很惊讶这里有多少答案无法理解一个简单的概念:浏览应用程序中的控件并不是视图本身应该做的事情。 控制器的工作是决定使哪个控制器成为下一个第一响应者。

此外,大多数答案仅适用于向前导航,但用户可能也想要倒退。

所以这就是我想出来的。 您的表单应由视图控制器管理,视图控制器是响应程序链的一部分。 所以你可以完全自由地实现以下方法:

#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];
}

可以应用用于预先滚动屏幕外响应者的附加逻辑。

这种方法的另一个优点是你不需要子类化你可能想要显示的各种控件(比如UITextField ),而是可以在控制器级别管理逻辑,说实话,这是正确的地方 。所以。


#17楼

您可以使用IQKeyboardManager库来执行此操作。 它处理所有事情,你不需要任何额外的setup.IQKeyboardManager可以通过CocoaPods,安装它只需将以下行添加到你的Podfile:

pod 'IQKeyboardManager'

或者只是将IQKeyBoardManager目录从演示项目拖放到您的项目中。 而已。 你可以从https://github.com/hackiftekhar/IQKeyboardManager找到IQKeyBoardManager目录


#18楼

更一致和更健壮的方法是使用NextResponderTextField您可以完全从界面构建器配置它,而无需设置委托或使用view.tag

你需要做的就是

  1. UITextField的类类型设置为NextResponderTextField
  2. 然后设置nextResponderField的出口指向下一个响应者,它可以是任何UITextField或任何UIResponder子类。 它也可以是一个UIButton,并且该库足够聪明,只有在启用时才能触发按钮的TouchUpInside事件。

这是图书馆的行动:


#19楼

我刚刚在处理GNTextFieldsCollectionManager这个东西时创建了新的Pod。 它会自动处理下一个/最后一个textField问题,并且非常易于使用:

[[GNTextFieldsCollectionManager alloc] initWithView:self.view];

抓取按视图层次结构(或标记)显示的所有文本字段,或者您可以指定自己的textFields数组。


#20楼

这在Xamarin.iOS / Monotouch中适用于我。 将键盘按钮更改为Next,将控件传递给下一个UITextField,并在最后一个UITextField之后隐藏键盘。

private void SetShouldReturnDelegates(IEnumerable<UIView> subViewsToScout )
{foreach (var item in subViewsToScout.Where(item => item.GetType() == typeof (UITextField))){(item as UITextField).ReturnKeyType = UIReturnKeyType.Next;(item as UITextField).ShouldReturn += (textField) =>{nint nextTag = textField.Tag + 1;var nextResponder = textField.Superview.ViewWithTag(nextTag);if (null != nextResponder)nextResponder.BecomeFirstResponder();elsetextField.Superview.EndEditing(true); //You could also use textField.ResignFirstResponder(); return false; // We do not want UITextField to insert line-breaks.};}
}

ViewDidLoad中你将拥有:

如果您的TextFields现在没有设置标签:

txtField1.Tag = 0;
txtField2.Tag = 1;
txtField3.Tag = 2;
//...

只是电话

SetShouldReturnDelegates(yourViewWithTxtFields.Subviews.ToList());
//If you are not sure of which view contains your fields you can also call it in a safer way:
SetShouldReturnDelegates(txtField1.Superview.Subviews.ToList());
//You can also reuse the same method with different containerViews in case your UITextField are under different views.

#21楼

一个快速扩展,应用mxcl的答案,使这特别容易(适应旅行者swift 2.3):

extension UITextField {class func connectFields(fields:[UITextField]) -> Void {guard let last = fields.last else {return}for i in 0 ..< fields.count - 1 {fields[i].returnKeyType = .Nextfields[i].addTarget(fields[i+1], action: "becomeFirstResponder", forControlEvents: .EditingDidEndOnExit)}last.returnKeyType = .Donelast.addTarget(last, action: #selector(UIResponder.resignFirstResponder), forControlEvents: .EditingDidEndOnExit)}
}

它易于使用:

UITextField.connectFields([field1, field2, field3])

对于除最后一个字段之外的所有字段,扩展名将返回按钮设置为“Next”,对于最后一个字段,将“返回”按钮设置为“完成”,并在点击这些按钮时移动焦点/关闭键盘。

斯威夫特<2.3

extension UITextField {class func connectFields(fields:[UITextField]) -> Void {guard let last = fields.last else {return}for var i = 0; i < fields.count - 1; i += 1 {fields[i].returnKeyType = .Nextfields[i].addTarget(fields[i+1], action: "becomeFirstResponder", forControlEvents: .EditingDidEndOnExit)}last.returnKeyType = .Donelast.addTarget(last, action: "resignFirstResponder", forControlEvents: .EditingDidEndOnExit)}
}

SWIFT 3:像这样使用 -

UITextField.connectFields(fields: [field1, field2])Extension:extension UITextField {class func connectFields(fields:[UITextField]) -> Void {guard let last = fields.last else {return}for i in 0 ..< fields.count - 1 {fields[i].returnKeyType = .nextfields[i].addTarget(fields[i+1], action: #selector(UIResponder.becomeFirstResponder), for: .editingDidEndOnExit)}last.returnKeyType = .golast.addTarget(last, action: #selector(UIResponder.resignFirstResponder), for: .editingDidEndOnExit)}}

#22楼

这是一个简单的快速解决方案,没有标签使用,没有故事板技巧......

只需使用此扩展程序:

extension UITextField{func nextTextFieldField() -> UITextField?{//field to returnvar returnField : UITextField?if self.superview != nil{//for each view in superviewfor (_, view) in self.superview!.subviews.enumerate(){//if subview is a text's fieldif view.isKindOfClass(UITextField){//cast curent view as text fieldlet currentTextField = view as! UITextField//if text field is after the current oneif currentTextField.frame.origin.y > self.frame.origin.y{//if there is no text field to return alreadyif returnField == nil {//set as default returnreturnField = currentTextField}//else if this this less far than the otherelse if currentTextField.frame.origin.y < returnField!.frame.origin.y{//this is the field to returnreturnField = currentTextField}}}}}//end of the mdethodreturn returnField}}

并使用您的textfield委托调用它(例如):

func textFieldShouldReturn(textField: UITextField) -> Bool {textField.resignFirstResponder()textField.nextTextFieldField()?.becomeFirstResponder()return true
}

#23楼

我尝试了很多代码,最后,这在Swift 3.0中为我工作最新[2017年3月]

ViewController类应继承UITextFieldDelegate以使此代码正常工作。

class ViewController: UIViewController,UITextFieldDelegate

添加带有正确标记号的文本字段,此标记号用于根据分配给它的增量标记号将控件带到适当的文本字段。

override func viewDidLoad() {userNameTextField.delegate = selfuserNameTextField.tag = 0userNameTextField.returnKeyType = UIReturnKeyType.nextpasswordTextField.delegate = selfpasswordTextField.tag = 1passwordTextField.returnKeyType = UIReturnKeyType.go
}

在上面的代码中, returnKeyType = UIReturnKeyType.next将使Key pad返回键显示为Next你还有其他选项如Join/Go等,根据你的应用程序更改值。

这个textFieldShouldReturn是一个UITextFieldDelegate控制的方法,这里我们有基于Tag值增量的下一个字段选择

func textFieldShouldReturn(_ textField: UITextField) -> Bool {if let nextField = textField.superview?.viewWithTag(textField.tag + 1) as? UITextField {nextField.becomeFirstResponder()} else {textField.resignFirstResponder()return true;}return false}

#24楼

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 = selfself.phoneTextField.delegate = self// Set your return typeself.phoneTextField.returnKeyType = .nextself.passwordTextField.returnKeyType = .done}func textFieldShouldReturn(_ textField: UITextField) -> Bool{if textField == self.phoneTextField {self.passwordTextField.becomeFirstResponder()}else if textField == self.passwordTextField{// Call login apiself.login()}return true}}

#25楼

如果有人想这样。 我认为这是最接近有关要求的要求

以下是我实现这一点的方法

使用为每个要进行设置的文本字段添加附件视图

func setAccessoryViewFor(textField : UITextField)    {let toolBar = UIToolbar()toolBar.barStyle = .defaulttoolBar.isTranslucent = truetoolBar.sizeToFit()// Adds the buttons// Add previousButtonlet prevButton = UIBarButtonItem(title: "<", style: .plain, target: self, action: #selector(previousPressed(sender:)))prevButton.tag = textField.tagif getPreviousResponderFor(tag: textField.tag) == nil {prevButton.isEnabled = false}// Add nextButtonlet nextButton = UIBarButtonItem(title: ">", style: .plain, target: self, action: #selector(nextPressed(sender:)))nextButton.tag = textField.tagif 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 = truetextField.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标签,您希望下一个/ prev按钮响应。


#26楼

大家好,请看这个

- (void)nextPrevious:(id)sender
{UIView *responder = [self.view findFirstResponder];   if (nil == responder || ![responder isKindOfClass:[GroupTextField class]]) {return;}switch([(UISegmentedControl *)sender selectedSegmentIndex]) {case 0:// previousif (nil != ((GroupTextField *)responder).previousControl) {[((GroupTextField *)responder).previousControl becomeFirstResponder];DebugLog(@"currentControl: %i previousControl: %i",((GroupTextField *)responder).tag,((GroupTextField *)responder).previousControl.tag);}break;case 1:// nextif (nil != ((GroupTextField *)responder).nextControl) {[((GroupTextField *)responder).nextControl becomeFirstResponder];DebugLog(@"currentControl: %i nextControl: %i",((GroupTextField *)responder).tag,((GroupTextField *)responder).nextControl.tag);}     break;    }
}

#27楼

还有一个优雅解决方案,它把我吓倒了,我第一次看到它。 优点:

  • 更接近OSX文本字段实现,其中文本字段知道下一个焦点应该去哪里
  • 不依赖于设置或使用标签 - 这对于这个用例来说是IMO脆弱的
  • 可以扩展为使用UITextFieldUITextView控件 - 或任何键盘输入UI控件
  • 不会使用样板文件UITextField委托代码来混淆视图控制器
  • 与IB完美集成,可以通过熟悉的选项 - 拖放来配置连接插座。

创建一个UITextField子类,它具有一个名为nextField的IBOutlet属性。 这是标题:

@interface SOTextField : UITextField@property (weak, nonatomic) IBOutlet UITextField *nextField; @end

这是实施:

@implementation SOTextField@end

在视图控制器中,您将创建-textFieldShouldReturn: delegate方法:

- (BOOL)textFieldShouldReturn:(UITextField *)textField {if ([textField isKindOfClass:[SOTextField class]]) {UITextField *nextField = [(SOTextField *)textField nextField];if (nextField) {dispatch_async(dispatch_get_current_queue(), ^{[nextField becomeFirstResponder];});}else {[textField resignFirstResponder];}}return YES;
}

在IB中,更改您的UITextField以使用SOTextField类。 接下来,同样在IB中,将每个'SOTextFields'的委托设置为'文件所有者'(这是您放置委托方法的代码的位置 - textFieldShouldReturn)。 这种设计的优点在于,现在您只需右键单击任何textField,并将nextField出口分配给您希望成为下一个响应者的下一个SOTextField对象。

此外,你可以做很酷的事情,比如循环textFields,这样在最后一个失去焦点后,第一个会再次获得焦点。

这可以很容易地扩展到自动分配returnKeyType的的SOTextFieldUIReturnKeyNext如果有nextField分配-少了一个东西手动配置。


#28楼

这是我解决这个问题的方法。

为了解决这个问题(因为我讨厌依赖标签来做东西),我决定在UITextField对象中添加一个自定义属性。 换句话说,我在UITextField上创建了一个类别,如下所示:

的UITextField + Extended.h

@interface UITextField (Extended)@property(retain, nonatomic)UITextField* nextTextField;@end

的UITextField + Extended.m

#import "UITextField+Extended.h"
#import <objc/runtime.h>static char defaultHashKey;@implementation UITextField (Extended)- (UITextField*) nextTextField { return objc_getAssociatedObject(self, &defaultHashKey);
}- (void) setNextTextField:(UITextField *)nextTextField{objc_setAssociatedObject(self, &defaultHashKey, nextTextField, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}@end

现在,这是我如何使用它:

UITextField *textField1 = ...init your textfield
UITextField *textField2 = ...init your textfield
UITextField *textField3 = ...init your textfieldtextField1.nextTextField = textField2;
textField2.nextTextField = textField3;
textField3.nextTextField = nil;

并实现textFieldShouldReturn方法:

- (BOOL)textFieldShouldReturn:(UITextField *)theTextField {UITextField *next = theTextField.nextTextField;if (next) {[next becomeFirstResponder];} else {[theTextField resignFirstResponder];}return NO;
}

我现在有一个UITextField的链接列表,每个人都知道谁在下一行。

希望它会有所帮助。


#29楼

如果没有使用标签并且没有为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];}];

#30楼

按下“完成”按钮时,解除键盘的一种非常简单的方法是:

在标题中创建一个新的IBAction

- (IBAction)textFieldDoneEditing:(id)sender;

在实现文件(.m文件)中添加以下方法:

- (IBAction)textFieldDoneEditing:(id)sender
{ [sender resignFirstResponder];
}

然后,当您将IBAction链接到文本字段时 - 链接到“退出时结束”事件。

如何浏览文本字段(下一个/完成按钮)相关推荐

  1. mysql 主键 下一个值_INNODB自增主键的一些问题 vs mysql获得自增字段下一个值

    root@localhost : test 04:23:28>show variables like 'innodb_autoinc_lock_mode'; +----------------- ...

  2. INNODB自增主键的一些问题 vs mysql获得自增字段下一个值

    今天发现 批量插入下,自增主键不连续了....... InnoDB AUTO_INCREMENT Lock Modes This section describes the behavior of A ...

  3. 添加删除按钮html代码怎么写,JavaScript添加一个文本框并带有删除按钮

    JavaScript添加一个文本框并带有删除按钮属于前端实例代码,有关更多实例代码大家可以查看. 实际操作中可能需要动态的创建和删除一个元素,比较常见是添加一个文本框和一个删除按钮,点击删除按钮可以删 ...

  4. UITextField 文本字段控件 -- IOS (解决键盘遮住View及密文設定的问题)(实例)

    进入本文之前建议你认真读一读我的另一篇博文:UIControl IOS控件编程 这样会起到事半功倍效果. 为什么要看另一篇关于UIControl的文章呢?因为UITextField继承自UIContr ...

  5. SAP-ABAP-基础-如何调试程序,debug模式下的一些按钮

    1.找程序名 1.1通过事物代码找程序名称 一般遇到问题都能知道哪个事物代码,已知事务代码可以通过SE93查找对应的程序名称 也可以通过事务代码进入程序之后点击 系统-->状态找到对应的程序 1 ...

  6. java如何创建一个文本框_创建一个有文本框和三个按钮的程序。当按下某个按钮时,使不同的文字(Java..._考试资料网...

    问答题创建一个有文本框和三个按钮的程序.当按下某个按钮时,使不同的文字("Java","编程","不难学")显示在文本框中.已经给出部分代码 ...

  7. jsf用于页面判断的标签_JSF –在JSF视图页面中添加标签,图像,按钮和文本字段

    jsf用于页面判断的标签 There are various UI components that JSF framework includes by default. Let us see some ...

  8. ios html 表单,iOS Safari HTML表单下一个/上一个按钮 - 它们如何工作?

    免责声明:我正在使用JQuery Mobile. 我有一堆不同形式的页面,但是当按下下一个/上一个按钮时,其中一些页面似乎表现出不同的行为. 所有表单都使用制表符索引进行设置. Form 1完美运行, ...

  9. 试设计一个窗口,内含一个按钮。开始运行时,按钮显示“Click Me”字样,当按钮按下时,按钮显示为“Click Me Again”字样,再按一次,则按钮显示“Click Me”字样,依此循环。

    试设计一个窗口,内含一个按钮.开始运行时,按钮显示"Click Me"字样,当按钮按下时,按钮显示为"Click Me Again"字样,再按一次,则按钮显示& ...

最新文章

  1. 知识蒸馏原来不是你想的那样子
  2. js图片轮换显示实例(转载)
  3. sparksql删除MySQL数据_Databricks 第6篇:Spark SQL 维护数据库和表
  4. pythn3随笔-enumerate()
  5. python remove函数_python中remove函数的用法是什么?
  6. libco协程库源码解读
  7. 第三讲系统的基本操作
  8. sublime自定义snippet代码片段
  9. Harmony OS — TabList和Tab分页栏
  10. 工作流分支走向流线条件配置
  11. wifi密码怎么重新设置
  12. MessageQueue nativePollOnce 一个不一样的 ANR
  13. oracle用户LOCKED(TIMED)原因及解决
  14. 中国医药中间体行业盈利状况与竞争趋势预测报告(新版)2022-2027年
  15. IOC 之深入理解 Spring IoC
  16. 高数笔记(四):导数概念,函数的求导法则,高阶导数,隐函数求导、参数方程求导
  17. 人生就像一张茶几,摆满了各种杯具/洗具/餐具!
  18. Vmware上安装openstack(Queens版)
  19. MIKE与SMS网格的区别
  20. java单根结构_对象导论:单根继承结构

热门文章

  1. Android开发工作中遇到的重点和难点总结
  2. Installation error: INSTALL_FAILED_CANCELLED_BY_USER
  3. Android异步消息处理机制 全解析
  4. 微信小游戏开发教程-2D游戏原理讲解
  5. (0109)iOS开发之CocoaPods Mac App的安装和使用
  6. uniapp中radio颜色渐变
  7. Http协议 详解(转载)
  8. 1002: A+B for Input-Output Practice (II)
  9. 关于 OneAPM Cloud Test DNS 监控的几个重要问题
  10. IIS6.0 日期格式问题