Подтвердить что ты не робот

Панель инструментов с "Предыдущая" и "Следующая" для ввода клавиатурыAccessoryView

Я пытаюсь реализовать эту панель инструментов, где только кнопка "Далее" включена, когда верхний textField является первымResponder, и только кнопка "Предыдущая" включена, когда нижний текстовый фильтр является первымResponder.

Это работает, но что происходит, мне нужно дважды нажимать кнопки "Предыдущий" / "Далее" два раза, чтобы включить/отключить противоположную кнопку.

Я пропустил что-то в цепочке ответчиков, чтобы это произошло?

Здесь мой код:

- (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 [email protected]"Bottom one";
        [self.topText becomeFirstResponder];
    }
}


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

Ответ 1

Хорошо, посмотрев на блестящую BSKeyboardControls, я попытался реализовать включение и отключение сегментированного элемента управления в textFieldDidBeginEditing, а не где my @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 [email protected]"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];
    }
}

Ответ 2

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

В UITextFieldDelegate

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

    return true
}

Ответ 3

Мое предложение здесь - "не изобретать велосипед".

Наличие кнопки Prev и Next над клавиатурой для переключения между UITextView настолько распространено, что вы можете найти много хороших реализаций, готовых к использованию.

Обратите внимание BSKeyboardControl.

Ответ 4

Вот расширение UIViewController, которое я использую всякий раз, когда мне нужна группа UITextField, чтобы обеспечить навигацию через входную аксессуар. Не нужно использовать делегирование UITextField с этим подходом и добавление поведения к нескольким формам, но приходит однострочный. Также поддерживается кнопка "Готово" для отклонения.

extension UIViewController {
    func addInputAccessoryForTextFields(textFields: [UITextField], dismissable: Bool = true, previousNextable: Bool = false) {
        for (index, textField) in textFields.enumerate() {
            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.enabled = 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.enabled = false
                } else {
                    nextButton.target = textFields[index + 1]
                    nextButton.action = #selector(UITextField.becomeFirstResponder)
                }

                items.appendContentsOf([previousButton, nextButton])
            }

            let spacer = UIBarButtonItem(barButtonSystemItem: .FlexibleSpace, target: nil, action: nil)
            let doneButton = UIBarButtonItem(barButtonSystemItem: .Done, target: view, action: #selector(UIView.endEditing))
            items.appendContentsOf([spacer, doneButton])

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

Пример:

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

Вот разумный значок стрелки.

Ответ 5

Вы также можете попробовать pod UITextField-Navigation:

pod 'UITextField-Navigation'

Он добавляет два ленивых свойства nextTextField и previousTextField к любому UITextField. Все, что вам нужно, это указать nextTextField либо в построителе интерфейса, либо программно, и панель инструментов добавлена ​​на клавиатуру для вас.

Программный:

import UITextField_Navigation

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

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

В построителе интерфейса:

connect nextTextField в построителе интерфейса введите описание изображения здесь

Ответ 6

Обновлено для Swift 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
}()

И затем:

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

Не забудьте изменить параметр "ContactViewController" на имя вашего контроллера просмотра.

Ответ 7

Попробуйте следующее: -

- (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 [email protected]"Bottom one";
    [self.topText becomeFirstResponder];
}
}


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

вам не нужно включать другой элемент, поскольку они повторно инициализируются каждый раз, когда изменяется клавиатура....