22

私はこのツールバーを実装しようとしてきました。ここでは、上部の textField が firstResponder の場合は「次へ」ボタンのみが有効になり、下部の textField が firstResponder の場合は「前へ」ボタンのみが有効になります。

それはうまくいきますが、「前へ」/「次へ」ボタンを毎回2回タップして、反対側のボタンを有効/無効にする必要があります。

これを実現しているレスポンダーチェーンに何かが欠けていますか?

これが私のコードです:

- (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];
    }
}
4

7 に答える 7

33

これは、入力アクセサリを介してナビゲーションを提供するために のUIViewControllerグループが必要なときにいつでも使用する拡張機能です。UITextFieldこのアプローチでは委任を使用する必要はなくUITextField、動作を複数のフォームに追加するだけで済みます。閉じるための「完了」ボタンもサポートしています。

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
    }
  }
}

例:

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

これは合理的な矢印アイコンです。

于 2016-05-10T04:10:33.303 に答える
11

さて、見事なBSKeyboardControlstextFieldDidBeginEditingを見た後、私がいた場所ではなく、でセグメント化されたコントロールの有効化と無効化を実装しようとしまし@selectorた。セグメント化されたコントロールの変数も導入しました。それは今動作します。修正されたコード スニペットは次のとおりです。

- (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];
    }
}
于 2013-01-04T13:57:07.123 に答える
7

ここでの私の提案は、「車輪を再発明しない」ことです。

sを切り替えるためにキーボード上にPrevとボタンを配置することは非常に一般的であるため、すぐに使用できる優れた実装が多数見つかります。NextUITextView

たとえば、 BSKeyboardControlをチェックしてください。

于 2013-01-03T23:07:46.567 に答える
2

ポッドUITextField-Navigationを試すこともできます:

pod 'UITextField-Navigation'

2 つの遅延読み込みプロパティを任意の UITextField に追加nextTextFieldpreviousTextFieldます。nextTextFieldインターフェイス ビルダーまたはプログラムでを指定するだけで、ツールバーがキーボードに追加されます。

プログラムで:

import UITextField_Navigation

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

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

Interface Builder で:

Interface Builder で nextTextField を接続する ここに画像の説明を入力

于 2016-06-20T08:51:26.300 に答える