我如何通过iPhone键盘上的“下一步”按钮浏览所有的文本字段?
最后一个文本字段应该关闭键盘。
我已经设置了IB按钮(下一步/完成),但现在我卡住了。
我实现了textFieldShouldReturn动作,但现在下一步和完成按钮关闭键盘。
我如何通过iPhone键盘上的“下一步”按钮浏览所有的文本字段?
最后一个文本字段应该关闭键盘。
我已经设置了IB按钮(下一步/完成),但现在我卡住了。
我实现了textFieldShouldReturn动作,但现在下一步和完成按钮关闭键盘。
当前回答
-(BOOL)textFieldShouldReturn:(UITextField *)textField
{
[[self.view viewWithTag:textField.tag+1] becomeFirstResponder];
return YES;
}
其他回答
在textFieldShouldReturn你应该检查你目前的文本域不是最后一个,当他们点击下一步,如果不是不要解散键盘..
这是一个简单的解决方案在swift,没有标签使用,没有故事板技巧…
只需使用这个扩展:
extension UITextField{
func nextTextFieldField() -> UITextField?{
//field to return
var returnField : UITextField?
if self.superview != nil{
//for each view in superview
for (_, view) in self.superview!.subviews.enumerate(){
//if subview is a text's field
if view.isKindOfClass(UITextField){
//cast curent view as text field
let currentTextField = view as! UITextField
//if text field is after the current one
if currentTextField.frame.origin.y > self.frame.origin.y{
//if there is no text field to return already
if returnField == nil {
//set as default return
returnField = currentTextField
}
//else if this this less far than the other
else if currentTextField.frame.origin.y < returnField!.frame.origin.y{
//this is the field to return
returnField = currentTextField
}
}
}
}
}
//end of the mdethod
return returnField
}
}
并调用它像这样(例如)与你的textfield委托:
func textFieldShouldReturn(textField: UITextField) -> Bool {
textField.resignFirstResponder()
textField.nextTextFieldField()?.becomeFirstResponder()
return true
}
如果有人想这样。我认为这是最接近问题所要求的要求
下面是我如何实现它
为需要设置的每个文本字段添加附件视图,使用
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标记。
这对我在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();
else
textField.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.
我已经实现了在视图层次结构中通过Responders导航的动态解决方案。其思想是,在整个层次结构中搜索下一个可能的响应器,根据需要向前或向后搜索。
UIView搜索扩展:
UIView+Cat.h
- (UIResponder *)getNextFirstResponder;
- (UIResponder *)getPreviousFirstResponder;
UIView+Cat.m
- (UIResponder *)getPreviousFirstResponder {
if (!self.superview) {
return nil;
}
BOOL hasreachedself = NO;
for (NSInteger i = self.superview.subviews.count-1; i >= 0; i--) {
UIView *v = [self.superview.subviews objectAtIndex:i];
if (v == self) {
hasreachedself = YES;
continue;
}
if (!hasreachedself) continue;
if ([v canBecomeFirstResponder] && !v.hidden) {
return v;
}
UIResponder *subResponder = [self getNextFirstResponderInView:v];
if (subResponder) {
return subResponder;
}
}
//search hierachicaly in superviews
return [self.superview getPreviousFirstResponder];
}
- (UIResponder *)getNextFirstResponder {
if (!self.superview) {
return nil;
}
BOOL hasreachedself = NO;
for (UIView *v in self.superview.subviews) {
if (v == self) {
hasreachedself = YES;
continue;
}
if (!hasreachedself) continue;
if ([v canBecomeFirstResponder] && !v.hidden) {
return v;
}
UIResponder *subResponder = [self getNextFirstResponderInView:v];
if (subResponder) {
return subResponder;
}
}
//search hierachicaly in superviews
return [self.superview getNextFirstResponder];
}
- (UIResponder *)getNextFirstResponderInView:(UIView *)view {
if ([view canBecomeFirstResponder] && !view.hidden) {
return view;
}
for (UIView *v in view.subviews) {
UIResponder *subResponder = [self getNextFirstResponderInView:v];
if (subResponder) {
return subResponder;
}
}
return nil;
}
用法:添加UIToolbar到UITextField / UITextView(在类别或子类中):
- (void)addToolbarInputAccessoryView {
UIToolbar *toolbar = [[UIToolbar alloc] initWithFrame:CGRectZero];
UIBarButtonItem *prev = [[UIBarButtonItem alloc] initWithImage:[UIImage systemImageNamed:@"chevron.up"] style:UIBarButtonItemStylePlain target:self action:@selector(moveToPreviousFirstResponder)];
UIBarButtonItem *next = [[UIBarButtonItem alloc] initWithImage:[UIImage systemImageNamed:@"chevron.down"] style:UIBarButtonItemStylePlain target:self action:@selector(moveToNextFirstResponder)];
UIBarButtonItem *space = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
UIBarButtonItem *done = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(hideKeyboard)];
toolbar.items = @[prev, next, space, done];
if ([[UITextField appearance] keyboardAppearance] == UIKeyboardAppearanceDark) {
toolbar.barStyle = UIBarStyleBlack;
toolbar.translucent = YES;
[toolbar setBarTintColor:[UIColor blackColor]];
[toolbar setTintColor:[UIColor whiteColor]];
}
[toolbar sizeToFit];
self.inputAccessoryView = toolbar;
}
- (void)hideKeyboard {
[self resignFirstResponder];
}
- (void)moveToNextFirstResponder {
UIResponder *next = [self getNextFirstResponder];
if (next) {
[next becomeFirstResponder];
}
else {
[self resignFirstResponder];
}
}
- (void)moveToPreviousFirstResponder {
UIResponder *prev = [self getPreviousFirstResponder];
if (prev) {
[prev becomeFirstResponder];
}
else {
[self resignFirstResponder];
}
}