简体   繁体   English

带有键盘输入的“上一个”和“下一个”的工具栏AccessoryView

[英]Toolbar with “Previous” and “Next” for Keyboard inputAccessoryView

I've been trying to implement this toolbar, where only the 'Next' button is enabled when the top textField is the firstResponder and only the 'Previous' button is enabled when the bottom textField is the firstResponder.我一直在尝试实现这个工具栏,当顶部 textField 是 firstResponder 时只启用“Next”按钮,当底部 textField 是 firstResponder 时只启用“Previous”按钮。

It kind of works, but what keeps happening is I need to tap the 'Previous'/'Next' buttons twice each time to enable/disable the opposing button.它有点工作,但不断发生的是我每次需要点击“上一个”/“下一个”按钮两次以启用/禁用相反的按钮。

Am I missing something in the responder chain that's making this happen?我是否在响应链中遗漏了一些导致这种情况发生的东西?

Here's my code:这是我的代码:

- (void)viewDidLoad
{
    [super viewDidLoad];
    [self.topText becomeFirstResponder];
}


- (UIToolbar *)keyboardToolBar {

    UIToolbar *toolbar = [[UIToolbar alloc] init];
    [toolbar setBarStyle:UIBarStyleBlackTranslucent];
    [toolbar sizeToFit];

    UISegmentedControl *segControl = [[UISegmentedControl alloc] initWithItems:@[@"Previous", @"Next"]];
    [segControl setSegmentedControlStyle:UISegmentedControlStyleBar];
    segControl.momentary = YES;
    segControl.highlighted = YES;

    [segControl addTarget:self action:@selector(changeRow:) forControlEvents:(UIControlEventValueChanged)];
    [segControl setEnabled:NO forSegmentAtIndex:0];

    UIBarButtonItem *nextButton = [[UIBarButtonItem alloc] initWithCustomView:segControl];

    NSArray *itemsArray = @[nextButton];

    [toolbar setItems:itemsArray];

    return toolbar;
}

- (void)changeRow:(id)sender {

    int idx = [sender selectedSegmentIndex];

    if (idx == 1) {
        [sender setEnabled:NO forSegmentAtIndex:1];
        [sender setEnabled:YES forSegmentAtIndex:0];
        self.topText.text = @"Top one";
        [self.bottomText becomeFirstResponder];
    }
    else {
        [sender setEnabled:NO forSegmentAtIndex:0];
        [sender setEnabled:YES forSegmentAtIndex:1];
        self.bottomText.text =@"Bottom one";
        [self.topText becomeFirstResponder];
    }
}


-(void)textFieldDidBeginEditing:(UITextField *)textField {
    if (!textField.inputAccessoryView) {
        textField.inputAccessoryView = [self keyboardToolBar];
    }
}

Here is a UIViewController extension that I use whenever I need a group of UITextField s to provide navigation via input accessory.这是一个UIViewController扩展,每当我需要一组UITextField来通过输入附件提供导航时,我都会使用它。 No need to use UITextField delegation with this approach, and adding the behavior to multiple forms becomes a single-liner.这种方法不需要使用UITextField委托,并且将行为添加到多个表单成为单行。 Also supports the 'Done' button to dismiss.还支持“完成”按钮关闭。

extension UIViewController {
  func addInputAccessoryForTextFields(textFields: [UITextField], dismissable: Bool = true, previousNextable: Bool = false) {
    for (index, textField) in textFields.enumerated() {
      let toolbar: UIToolbar = UIToolbar()
      toolbar.sizeToFit()

      var items = [UIBarButtonItem]()
      if previousNextable {
        let previousButton = UIBarButtonItem(image: UIImage(named: "Backward Arrow"), style: .plain, target: nil, action: nil)
        previousButton.width = 30
        if textField == textFields.first {
          previousButton.isEnabled = false
        } else {
          previousButton.target = textFields[index - 1]
          previousButton.action = #selector(UITextField.becomeFirstResponder)
        }

        let nextButton = UIBarButtonItem(image: UIImage(named: "Forward Arrow"), style: .plain, target: nil, action: nil)
        nextButton.width = 30
        if textField == textFields.last {
          nextButton.isEnabled = false
        } else {
          nextButton.target = textFields[index + 1]
          nextButton.action = #selector(UITextField.becomeFirstResponder)
        }
        items.append(contentsOf: [previousButton, nextButton])
      }

      let spacer = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
      let doneButton = UIBarButtonItem(barButtonSystemItem: .done, target: view, action: #selector(UIView.endEditing))
      items.append(contentsOf: [spacer, doneButton])


      toolbar.setItems(items, animated: false)
      textField.inputAccessoryView = toolbar
    }
  }
}

example:例子:

let field1 = UITextField()
let field2 = UITextField()
addInputAccessoryForTextFields([field1, field2], dismissable: true, previousNextable: true)

Here's a reasonable arrow icon .这是一个合理的箭头图标

Swift:迅速:

lazy var inputToolbar: UIToolbar = {
    var toolbar = UIToolbar()
    toolbar.barStyle = .default
    toolbar.translucent = true
    toolbar.sizeToFit()

    var doneButton = UIBarButtonItem(title: "Done", style: .bordered, target: self, action: "inputToolbarDonePressed")
    var flexibleSpaceButton = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
    var fixedSpaceButton = UIBarButtonItem(barButtonSystemItem: .fixedSpace, target: nil, action: nil)

    var nextButton  = UIBarButtonItem(image: UIImage(named: "keyboardPreviousButton"), style: .bordered, target: self, action: "keyboardNextButton")
    nextButton.width = 50.0
    var previousButton  = UIBarButtonItem(image: UIImage(named: "keyboardNextButton"), style: .Bordered, target: self, action: "keyboardPreviousButton")

    toolbar.setItems([fixedSpaceButton, nextButton, fixedSpaceButton, previousButton, flexibleSpaceButton, doneButton], animated: false)
    toolbar.userInteractionEnabled = true

    return toolbar
    }()

In UITextFieldDelegate在 UITextFieldDelegate 中

 func textFieldShouldBeginEditing(textField: UITextField) -> Bool {
    textField.inputAccessoryView = inputToolbar

    return true
}

Okay, after looking at the brilliant BSKeyboardControls , I tried implementing the enabling and disabling of the segmented control in textFieldDidBeginEditing , instead of where my @selector was.好的,在看了精彩的BSKeyboardControls 之后,我尝试在textFieldDidBeginEditing中实现分段控件的启用和禁用,而不是我的@selector所在的位置。 I also introduced a variable for the segmented control.我还为分段控制引入了一个变量。 It works now.它现在有效。 Here's the amended code snippet:这是修改后的代码片段:

- (void)viewDidLoad
{
    [super viewDidLoad];
    [self.topText becomeFirstResponder];
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];

}

- (UIToolbar *)keyboardToolBar {

    UIToolbar *toolbar = [[UIToolbar alloc] init];
    [toolbar setBarStyle:UIBarStyleBlackTranslucent];
    [toolbar sizeToFit];

    self.segControl = [[UISegmentedControl alloc] initWithItems:@[@"Previous", @"Next"]];
    [self.segControl setSegmentedControlStyle:UISegmentedControlStyleBar];
    self.segControl.momentary = YES;

    [self.segControl addTarget:self action:@selector(changeRow:) forControlEvents:(UIControlEventValueChanged)];
    [self.segControl setEnabled:NO forSegmentAtIndex:0];

    UIBarButtonItem *nextButton = [[UIBarButtonItem alloc] initWithCustomView:self.segControl];

    NSArray *itemsArray = @[nextButton];

    [toolbar setItems:itemsArray];

    return toolbar;
}

- (void)changeRow:(id)sender {

    int idx = [sender selectedSegmentIndex];

    if (idx) {
        self.topText.text = @"Top one";
        [self.bottomText becomeFirstResponder];
    }
    else {
        self.bottomText.text =@"Bottom one";
        [self.topText becomeFirstResponder];
    }
}


-(void)textFieldDidBeginEditing:(UITextField *)textField {

    if (!textField.inputAccessoryView) {

        textField.inputAccessoryView = [self keyboardToolBar];
    }
    if (textField.tag) {

        [self.segControl setEnabled:NO forSegmentAtIndex:1];
        [self.segControl setEnabled:YES forSegmentAtIndex:0];
    }
}

My suggestion here is "don't reinvent the wheel".我的建议是“不要重新发明轮子”。

Having Prev and Next button over a keyboard for switching between UITextView s is so common that you can find many good implementations ready to use.在键盘上有PrevNext按钮用于在UITextView之间切换是很常见的,你可以找到许多可以使用的好的实现。

Check out BSKeyboardControl , for instance.例如,查看BSKeyboardControl

Updated for Swift 3.0Swift 3.0更新

lazy var inputToolbar: UIToolbar = {
    var toolbar = UIToolbar()
    toolbar.barStyle = .default
    toolbar.isTranslucent = true
    toolbar.sizeToFit()

    var doneButton = UIBarButtonItem(title: "Done", style: .plain, target: self, action: #selector(ContactViewController.inputToolbarDonePressed))
    var flexibleSpaceButton = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
    var fixedSpaceButton = UIBarButtonItem(barButtonSystemItem: .fixedSpace, target: nil, action: nil)

    var nextButton = UIBarButtonItem(title: "Next", style: .plain, target: self, action: #selector(ContactViewController.keyboardNextButton))
    var previousButton = UIBarButtonItem(title: "Previous", style: .plain, target: self, action: #selector(ContactViewController.keyboardPreviousButton))

    toolbar.setItems([fixedSpaceButton, previousButton, fixedSpaceButton, nextButton, flexibleSpaceButton, doneButton], animated: false)
    toolbar.isUserInteractionEnabled = true

    return toolbar
}()

And then:接着:

func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
    textField.inputAccessoryView = inputToolbar
    return true
}

Remember to change thange "ContactViewController" to the name of your View Controller.请记住将“ContactViewController”更改为您的视图控制器的名称。

You can also try the pod UITextField-Navigation :您还可以尝试使用 pod UITextField-Navigation

pod 'UITextField-Navigation'

It adds two lazy-loaded properties nextTextField and previousTextField to any UITextField.它将两个延迟加载的属性nextTextFieldpreviousTextField到任何 UITextField。 All you need is to specify the nextTextField either on the interface builder or programmatically, and the toolbar is added to the keyboard for you.您只需要在界面构建器上或以编程方式指定nextTextField ,工具栏就会为您添加到键盘上。

Programmatically:以编程方式:

import UITextField_Navigation

let textField1 = UITextField()
let textField2 = UITextField()
textField1.nextTextField = textField2

assert(textField2 == textField1.nextTextField)
assert(textField1 == textField2.previousTextField)

On the Interface Builder:在界面生成器上:

在 Interface Builder 中连接 nextTextField 在此处输入图片说明

Try this :-试试这个 :-

- (void)viewDidLoad
{
[super viewDidLoad];
[self.topText becomeFirstResponder];
}
- (UIToolbar *)keyboardToolBar {

UIToolbar *toolbar = [[UIToolbar alloc] init];
[toolbar setBarStyle:UIBarStyleBlackTranslucent];
[toolbar sizeToFit];

UISegmentedControl *segControl = [[UISegmentedControl alloc]       initWithItems:@[@"Previous", @"Next"]];
[segControl setSegmentedControlStyle:UISegmentedControlStyleBar];
segControl.momentary = YES;
segControl.highlighted = YES;

[segControl addTarget:self action:@selector(changeRow:)  forControlEvents:(UIControlEventValueChanged)];
[segControl setEnabled:NO forSegmentAtIndex:0];

UIBarButtonItem *nextButton = [[UIBarButtonItem alloc] initWithCustomView:segControl];

NSArray *itemsArray = @[nextButton];

[toolbar setItems:itemsArray];

int idx = [sender selectedSegmentIndex];

if (idx == 1) {
    [sender setEnabled:NO forSegmentAtIndex:1];
}
else {
    [sender setEnabled:NO forSegmentAtIndex:0];
}

return toolbar;
}

- (void)changeRow:(id)sender {


int idx = [sender selectedSegmentIndex];

if (idx == 1) {
    self.topText.text = @"Top one";
    [self.bottomText becomeFirstResponder];
}
else {
    self.bottomText.text =@"Bottom one";
    [self.topText becomeFirstResponder];
}
}


-(void)textFieldDidBeginEditing:(UITextField *)textField {
if (!textField.inputAccessoryView) {
    textField.inputAccessoryView = [self keyboardToolBar];
}
}

you dont need to enable other item as they reinitialise every time when keyboard changes ....您不需要启用其他项目,因为每次键盘更改时它们都会重新初始化......

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 带有“上一个”和“下一个”的键盘工具栏 - Toolbar with “Previous” and “Next” for keyboard 在iOS8 WebView中删除自定义键盘的下一个/上一个按钮(inputAccessoryView) - Remove Next / Previous buttons (inputAccessoryView) for Custom Keyboard in iOS8 WebView 下一个/上一个键盘工具栏iOS7 - Next/Previous Keyboard Toolbar iOS7 QuickDialog在其inputaccessoryview中不显示“上一个”和“下一个”工具栏 - QuickDialog doesn't show 'prev' and 'next' toolbar as it's inputaccessoryview iOS 8-UIWebView键盘-上一个/下一个/完成附件栏-如何删除工具栏? - iOS 8 - UIWebView Keyboard - Previous/Next/Done Accessory Bar - How can I remove the toolbar? inputAccessoryView不在键盘上方显示 - inputAccessoryView not showing above keyboard 在iOS中的“下一个”或“上一个”虚拟键盘上 - On 'next' or 'previous' virtual keyboard in iOS 无法在Pickerview中设置inputAccessoryView工具栏 - Unable set inputAccessoryView toolbar in Pickerview Swift:在工具栏中添加已完成,下一个,上一个功能 - Swift: Add done, next, previous functions in toolbar CollectionViewController不适应使用InputAccessoryView显示的键盘 - CollectionViewController not adjusting for keyboard showing with InputAccessoryView
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM