热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

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

如何使用iPhone键盘上的“下一步”按钮浏览所有文本字段?最后一个文本字段应该关闭键盘。我已经设置了IB按钮(下一个完成),

如何使用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 &#61; [_inputFields indexOfObject:textField];index&#43;&#43;;if (index <_inputFields.count) {UIView *v &#61; [_inputFields objectAtIndex:index];[v becomeFirstResponder];}return NO;
}// for UITextView
-(BOOL)textView:(UITextView*)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString*)text {if ([&#64;"\n" isEqualToString:text]) {NSUInteger index &#61; [_inputFields indexOfObject:textView];index&#43;&#43;;if (index <_inputFields.count) {UIView *v &#61; [_inputFields objectAtIndex:index];[v becomeFirstResponder];} else {[self.view endEditing:YES];}return NO;}return YES;
}



#9楼

首先在xib中设置键盘返回键&#xff0c;否则你可以在viewdidload编写代码&#xff1a;

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



#10楼

这是一个没有代表团的人&#xff1a;

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

ObjC&#xff1a;

[tf1 addTarget:tf2 action:&#64;selector(becomeFirstResponder) forControlEvents:UIControlEventEditingDidEndOnExit];
[tf2 addTarget:tf3 action:&#64;selector(becomeFirstResponder) forControlEvents:UIControlEventEditingDidEndOnExit];

使用&#xff08;大多数未知的&#xff09; UIControlEventEditingDidEndOnExit UITextField操作。

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

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




#11楼

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

源和示例应用程序&#xff1a; UIControlsWithTabbing的GitHub存储库

用法&#xff1a;

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

在Interface Builder中分配nextControl

标题&#xff1a;

//
// UIControl&#43;NextControl.h
// UIControlsWithTabbing
//#import &#64;interface UIControl (NextControl)&#64;property (nonatomic, weak) IBOutlet UIControl *nextControl;- (BOOL)transferFirstResponderToNextControl;&#64;end

执行&#xff1a;

#import "UIControl&#43;NextControl.h"
#import static char defaultHashKey;&#64;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;
}&#64;end



#12楼

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



#13楼

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

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



#14楼

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

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

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

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




#15楼

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

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



#16楼

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

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

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

#pragma mark - Key Commands- (NSArray *)keyCommands
{static NSArray *commands;static dispatch_once_t once;dispatch_once(&once, ^{UIKeyCommand *const forward &#61; [UIKeyCommand keyCommandWithInput:&#64;"\t" modifierFlags:0 action:&#64;selector(tabForward:)];UIKeyCommand *const backward &#61; [UIKeyCommand keyCommandWithInput:&#64;"\t" modifierFlags:UIKeyModifierShift action:&#64;selector(tabBackward:)];commands &#61; &#64;[forward, backward];});return commands;
}- (void)tabForward:(UIKeyCommand *)command
{NSArray *const controls &#61; self.controls;UIResponder *firstResponder &#61; nil;for (UIResponder *const responder in controls) {if (firstResponder !&#61; nil && responder.canBecomeFirstResponder) {[responder becomeFirstResponder]; return;}else if (responder.isFirstResponder) {firstResponder &#61; responder;}}[controls.firstObject becomeFirstResponder];
}- (void)tabBackward:(UIKeyCommand *)command
{NSArray *const controls &#61; self.controls;UIResponder *firstResponder &#61; nil;for (UIResponder *const responder in controls.reverseObjectEnumerator) {if (firstResponder !&#61; nil && responder.canBecomeFirstResponder) {[responder becomeFirstResponder]; return;}else if (responder.isFirstResponder) {firstResponder &#61; responder;}}[controls.lastObject becomeFirstResponder];
}

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

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




#17楼

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

pod &#39;IQKeyboardManager&#39;

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




#18楼

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

你需要做的就是


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

这是图书馆的行动&#xff1a;

在此输入图像描述




#19楼

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

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

抓取按视图层次结构&#xff08;或标记&#xff09;显示的所有文本字段&#xff0c;或者您可以指定自己的textFields数组。




#20楼

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

private void SetShouldReturnDelegates(IEnumerable subViewsToScout )
{foreach (var item in subViewsToScout.Where(item &#61;> item.GetType() &#61;&#61; typeof (UITextField))){(item as UITextField).ReturnKeyType &#61; UIReturnKeyType.Next;(item as UITextField).ShouldReturn &#43;&#61; (textField) &#61;>{nint nextTag &#61; textField.Tag &#43; 1;var nextResponder &#61; textField.Superview.ViewWithTag(nextTag);if (null !&#61; 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中你将拥有&#xff1a;

如果您的TextFields现在没有设置标签&#xff1a;

txtField1.Tag &#61; 0;
txtField2.Tag &#61; 1;
txtField3.Tag &#61; 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楼

一个快速扩展&#xff0c;应用mxcl的答案&#xff0c;使这特别容易&#xff08;适应旅行者swift 2.3&#xff09;&#xff1a;

extension UITextField {class func connectFields(fields:[UITextField]) -> Void {guard let last &#61; fields.last else {return}for i in 0 ..}

它易于使用&#xff1a;

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

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

斯威夫特<2.3

extension UITextField {class func connectFields(fields:[UITextField]) -> Void {guard let last &#61; fields.last else {return}for var i &#61; 0; i }

SWIFT 3&#xff1a;像这样使用 -

UITextField.connectFields(fields: [field1, field2])Extension:extension UITextField {class func connectFields(fields:[UITextField]) -> Void {guard let last &#61; fields.last else {return}for i in 0 ..



#22楼

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

只需使用此扩展程序&#xff1a;

extension UITextField{func nextTextFieldField() -> UITextField?{//field to returnvar returnField : UITextField?if self.superview !&#61; nil{//for each view in superviewfor (_, view) in self.superview!.subviews.enumerate(){//if subview is a text&#39;s fieldif view.isKindOfClass(UITextField){//cast curent view as text fieldlet currentTextField &#61; 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 &#61;&#61; nil {//set as default returnreturnField &#61; currentTextField}//else if this this less far than the otherelse if currentTextField.frame.origin.y

并使用您的textfield委托调用它&#xff08;例如&#xff09;&#xff1a;

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



#23楼

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

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

class ViewController: UIViewController,UITextFieldDelegate

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

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

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

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

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



#24楼

Swift 3.1中的解决方案&#xff0c;在连接文本字段后&#xff0c;IBOutlets在viewDidLoad中设置文本字段委托&#xff0c;然后在textFieldShouldReturn中导航您的操作

class YourViewController: UIViewController,UITextFieldDelegate {&#64;IBOutlet weak var passwordTextField: UITextField!&#64;IBOutlet weak var phoneTextField: UITextField!override func viewDidLoad() {super.viewDidLoad()self.passwordTextField.delegate &#61; selfself.phoneTextField.delegate &#61; self// Set your return typeself.phoneTextField.returnKeyType &#61; .nextself.passwordTextField.returnKeyType &#61; .done}func textFieldShouldReturn(_ textField: UITextField) -> Bool{if textField &#61;&#61; self.phoneTextField {self.passwordTextField.becomeFirstResponder()}else if textField &#61;&#61; self.passwordTextField{// Call login apiself.login()}return true}}



#25楼

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

在此输入图像描述

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

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

func setAccessoryViewFor(textField : UITextField) {let toolBar &#61; UIToolbar()toolBar.barStyle &#61; .defaulttoolBar.isTranslucent &#61; truetoolBar.sizeToFit()// Adds the buttons// Add previousButtonlet prevButton &#61; UIBarButtonItem(title: "<", style: .plain, target: self, action: #selector(previousPressed(sender:)))prevButton.tag &#61; textField.tagif getPreviousResponderFor(tag: textField.tag) &#61;&#61; nil {prevButton.isEnabled &#61; false}// Add nextButtonlet nextButton &#61; UIBarButtonItem(title: ">", style: .plain, target: self, action: #selector(nextPressed(sender:)))nextButton.tag &#61; textField.tagif getNextResponderFor(tag: textField.tag) &#61;&#61; nil {nextButton.title &#61; "Done"}let spaceButton &#61; UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)toolBar.setItems([prevButton,spaceButton,nextButton], animated: false)toolBar.isUserInteractionEnabled &#61; truetextField.inputAccessoryView &#61; toolBar
}

使用以下功能来处理水龙头

func nextPressed(sender : UIBarButtonItem) {if let nextResponder &#61; getNextResponderFor(tag: sender.tag) {nextResponder.becomeFirstResponder()} else {self.view.endEditing(true)}}func previousPressed(sender : UIBarButtonItem) {if let previousResponder &#61; getPreviousResponderFor(tag : sender.tag) {previousResponder.becomeFirstResponder()}
}func getNextResponderFor(tag : Int) -> UITextField? {return self.view.viewWithTag(tag &#43; 1) as? UITextField
}func getPreviousResponderFor(tag : Int) -> UITextField? {return self.view.viewWithTag(tag - 1) as? UITextField
}

您需要按顺序给出textFields标签&#xff0c;您希望下一个/ prev按钮响应。




#26楼

大家好&#xff0c;请看这个

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



#27楼

还有一个优雅解决方案&#xff0c;它把我吓倒了&#xff0c;我第一次看到它。 优点&#xff1a;


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

创建一个UITextField子类&#xff0c;它具有一个名为nextField的IBOutlet属性。 这是标题&#xff1a;

&#64;interface SOTextField : UITextField&#64;property (weak, nonatomic) IBOutlet UITextField *nextField; &#64;end

这是实施&#xff1a;

&#64;implementation SOTextField&#64;end

在视图控制器中&#xff0c;您将创建-textFieldShouldReturn: delegate方法&#xff1a;

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

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

在IB中分配nextField

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

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




#28楼

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

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

的UITextField &#43; Extended.h

&#64;interface UITextField (Extended)&#64;property(retain, nonatomic)UITextField* nextTextField;&#64;end

的UITextField &#43; Extended.m

#import "UITextField&#43;Extended.h"
#import static char defaultHashKey;&#64;implementation UITextField (Extended)- (UITextField*) nextTextField { return objc_getAssociatedObject(self, &defaultHashKey);
}- (void) setNextTextField:(UITextField *)nextTextField{objc_setAssociatedObject(self, &defaultHashKey, nextTextField, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}&#64;end

现在&#xff0c;这是我如何使用它&#xff1a;

UITextField *textField1 &#61; ...init your textfield
UITextField *textField2 &#61; ...init your textfield
UITextField *textField3 &#61; ...init your textfieldtextField1.nextTextField &#61; textField2;
textField2.nextTextField &#61; textField3;
textField3.nextTextField &#61; nil;

并实现textFieldShouldReturn方法&#xff1a;

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

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

希望它会有所帮助。




#29楼

如果没有使用标签并且没有为nextField / nextTextField添加属性&#xff0c;您可以尝试使用它来模拟TAB&#xff0c;其中“testInput”是您当前的活动字段&#xff1a;

if ([textInput isFirstResponder])[textInput.superview.subviews enumerateObjectsAtIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange([textInput.superview.subviews indexOfObject:textInput]&#43;1,[textInput.superview.subviews count]-[textInput.superview.subviews indexOfObject:textInput]-1)]options:0 usingBlock:^(UIView *obj, NSUInteger idx, BOOL *stop) {*stop &#61; !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 &#61; !obj.hidden && [obj becomeFirstResponder];}];



#30楼

按下“完成”按钮时&#xff0c;解除键盘的一种非常简单的方法是&#xff1a;

在标题中创建一个新的IBAction

- (IBAction)textFieldDoneEditing:(id)sender;

在实现文件&#xff08;.m文件&#xff09;中添加以下方法&#xff1a;

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

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


推荐阅读
  • 在AngularJS中,有时需要在表单内包含某些控件,但又不希望这些控件导致表单变为脏状态。例如,当用户对表单进行修改后,表单的$dirty属性将变为true,触发保存对话框。然而,对于一些导航或辅助功能控件,我们可能并不希望它们触发这种行为。 ... [详细]
  • 使用 ModelAttribute 实现页面数据自动填充
    本文介绍了如何利用 Spring MVC 中的 ModelAttribute 注解,在页面跳转后自动填充表单数据。主要探讨了两种实现方法及其背后的原理。 ... [详细]
  • iOS如何实现手势
    这篇文章主要为大家展示了“iOS如何实现手势”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“iOS ... [详细]
  • 本文旨在探讨Swift中的Closure与Objective-C中的Block之间的区别与联系,通过定义、使用方式以及外部变量捕获等方面的比较,帮助开发者更好地理解这两种机制的特点及应用场景。 ... [详细]
  • 本文探讨了如何使用Scrapy框架构建高效的数据采集系统,以及如何通过异步处理技术提升数据存储的效率。同时,文章还介绍了针对不同网站采用的不同采集策略。 ... [详细]
  • 本文探讨了Android系统中联系人数据库的设计,特别是AbstractContactsProvider类的作用与实现。文章提供了对源代码的详细分析,并解释了该类如何支持跨数据库操作及事务处理。源代码可从官方Android网站下载。 ... [详细]
  • 本文探讨了一个Web工程项目的需求,即允许用户随时添加定时任务,并通过Quartz框架实现这些任务的自动化调度。文章将介绍如何设计任务表以存储任务信息和执行周期,以及如何通过一个定期扫描机制自动识别并加载新任务到调度系统中。 ... [详细]
  • This article explores the process of integrating Promises into Ext Ajax calls for a more functional programming approach, along with detailed steps on testing these asynchronous operations. ... [详细]
  • 将XML数据迁移至Oracle Autonomous Data Warehouse (ADW)
    随着Oracle ADW的推出,数据迁移至ADW成为业界关注的焦点。特别是XML和JSON这类结构化数据的迁移需求日益增长。本文将通过一个实际案例,探讨如何高效地将XML数据迁移至ADW。 ... [详细]
  • 本文介绍了使用Python和C语言编写程序来计算一个给定数值的平方根的方法。通过迭代算法,我们能够精确地得到所需的结果。 ... [详细]
  • 本文分享了作者在使用LaTeX过程中的几点心得,涵盖了从文档编辑、代码高亮、图形绘制到3D模型展示等多个方面的内容。适合希望深入了解LaTeX高级功能的用户。 ... [详细]
  • 本文详细介绍如何在SSM(Spring + Spring MVC + MyBatis)框架中实现分页功能。包括分页的基本概念、数据准备、前端分页栏的设计与实现、后端分页逻辑的编写以及最终的测试步骤。 ... [详细]
  • 本文详细探讨了Java中HashMap类的hash()方法的工作原理及其重要性,特别是在JDK 7版本中的实现。 ... [详细]
  • 视觉Transformer综述
    本文综述了视觉Transformer在计算机视觉领域的应用,从原始Transformer出发,详细介绍了其在图像分类、目标检测和图像分割等任务中的最新进展。文章不仅涵盖了基础的Transformer架构,还深入探讨了各类增强版Transformer模型的设计思路和技术细节。 ... [详细]
  • 尽管在WPF中工作了一段时间,但在菜单控件的样式设置上遇到了一些基础问题,特别是关于如何正确配置前景色和背景色。 ... [详细]
author-avatar
果粒粒1201
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有