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

Как установить порядок вкладок в iOS?

Есть ли способ (в IB или коде) установить порядок вкладок между текстовыми полями в представлении?

Обратите внимание, что я не говорю о следующем поле формы после нажатия кнопки (или "Далее" ) - на многих клавиатурах bluetooth есть клавиша табуляции, которая, по-видимому, проходит через поля в совершенно ином порядке. В моем конкретном случае этот порядок не соответствует позиции полей в представлении или даже порядку добавления полей. Изменение файла xib вручную для изменения NSNextKeyView тоже не имеет значения.

Кто-нибудь знает, как изменить этот порядок?

4b9b3361

Ответ 1

Я заинтересован в решении одной и той же проблемы, хотя до сих пор порядок по умолчанию, который выглядит слева направо, а затем сверху вниз, тот, который я хочу.

Я протестировал гипотезу о том, что курсор перемещается по глубине в первом порядке через дерево подзонов и супервизор, но это не true. Изменение порядка подзонов без изменения их местоположения не изменило порядок полей, пройденных нажатиями табуляции.

Одна из полезных функций заключается в том, что текстовое поле delegate textFieldShouldBeginEditing метод вызывается для каждого текстового поля в окне приложения. Если это возвращает NO, тогда текстовое поле не будет выбрано, поэтому, если вы можете определить свой желаемый порядок и сделать только правильный ответ, YES, это может решить вашу проблему.

Ответ 2

Ответ на

@sprocket был лишь несколько полезен. Просто потому, что что-то работает из коробки, не означает, что вы должны перестать думать о лучшем способе - или даже правильном пути - что-то делать. Поскольку он заметил, что поведение недокументировано, но оно больше всего подходит нашим потребностям.

Это было недостаточно для меня. Подумайте о языке RTL, и вкладки все равно будут отображаться слева направо, не говоря уже о том, что поведение полностью отличается от симулятора к устройству (устройство не фокусирует первый вход на вкладке). Самое главное, однако, реализация Apple без документов, кажется, рассматривает только взгляды, установленные в настоящее время в иерархии представлений.

Подумайте о форме в виде (не предназначенной для каламбура) табличного представления. Каждая ячейка содержит один элемент управления, поэтому не все элементы формы могут быть видны одновременно. Apple просто выполнит цикл резервного копирования, как только вы достигнете самого нижнего (на экране!) Управления, вместо прокрутки вниз. Это поведение, безусловно, не то, что мы хотим.

Итак, вот что я придумал. Ваша форма должна управляться контроллером представления, а контроллеры просмотра являются частью цепочки ответчиков. Таким образом, вы совершенно свободны в реализации следующих методов:

#pragma mark - Key Commands

- (NSArray *)keyCommands
{
    static NSArray *commands;

    static dispatch_once_t once;
    dispatch_once(&once, ^{
        UIKeyCommand *const forward = [UIKeyCommand keyCommandWithInput:@"\t" modifierFlags:0 action:@selector(tabForward:)];
        UIKeyCommand *const backward = [UIKeyCommand keyCommandWithInput:@"\t" modifierFlags:UIKeyModifierShift action:@selector(tabBackward:)];

        commands = @[forward, backward];
    });

    return commands;
}

- (void)tabForward:(UIKeyCommand *)command
{
    NSArray *const controls = self.controls;
    UIResponder *firstResponder = nil;

    for (UIResponder *const responder in controls) {
        if (firstResponder != nil && responder.canBecomeFirstResponder) {
            [responder becomeFirstResponder]; return;
        }
        else if (responder.isFirstResponder) {
            firstResponder = responder;
        }
    }

    [controls.firstObject becomeFirstResponder];
}

- (void)tabBackward:(UIKeyCommand *)command
{
    NSArray *const controls = self.controls;
    UIResponder *firstResponder = nil;

    for (UIResponder *const responder in controls.reverseObjectEnumerator) {
        if (firstResponder != nil && responder.canBecomeFirstResponder) {
            [responder becomeFirstResponder]; return;
        }
        else if (responder.isFirstResponder) {
            firstResponder = responder;
        }
    }

    [controls.lastObject becomeFirstResponder];
}

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

Другим преимуществом такого подхода является то, что вам не нужно подклассировать все виды элементов управления, которые вы можете отображать (например, UITextField s), но вместо этого можете управлять логикой на уровне контроллера, где, допустим, подходящее место для этого.

Ответ 3

Поведение клавиш Tab в ios будет выглядеть следующим образом: когда u нажимает вкладку на внешней клавиатуре - элемент управления перемещается по всем текстовым полям на этом экране, вызывая только метод shouldBeginEditing, где его возвращаемое значение также определяется Apple, которое не может быть отменено. После сканирования всех полей он вычисляет ближайшее X-позиционное поле по отношению к смещению вида от текущего текстового поля, а затем к ближайшему Y-позиционированному полю.

Также ничего не может быть сделано до тех пор, пока управление не поступит в метод textFieldDidBeginEditing.

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

Ответ 5

Зарегистрируйте UIKeyCommand для обнаружения нажатия клавиши табуляции. Я сделал это в своем текущем контроллере.

    self.addKeyCommand(UIKeyCommand(input: "\t", modifierFlags: [], action: #selector(tabKeyPressed)))

Внутри ключа tabKeyPressed handler найдите текущее активное поле, затем установите следующего ответчика. orderedTextFields - это массив UITextField в желаемом порядке вкладок.

func tabKeyPressed(){
    let activeField = getActiveField()
    if(activeField == nil){
        return
    }
    let nextResponder = getNextTextField(activeField!)
    nextResponder?.becomeFirstResponder()
}

func getActiveField() -> UITextField? {
    for textField in orderedTextFields {
        if(textField.isFirstResponder()){
            return textField
        }
    }
    return nil
}

func getNextTextField(current: UITextField) -> UITextField? {
    let index = orderedTextField.indexOf(current)
    if(orderedTextField.count-1 <= index!){
        return nil
    }
    return orderedTextField[index! + 1]
}

Ответ 7

Единственный способ, которым я обнаружил уникальное обнаружение нажатия клавиши Tab с физической клавиатуры, - это реализовать метод insertText: метод UIKeyInput для пользовательского объекта, который можетBecomeFirstResponder.

- (void)insertText:(NSString *)text {
    NSLog(@"text is equal to tab character: %i", [text isEqualToString:@"\t"]);
}

Мне не удалось заставить это работать при подклассификации UITextField, к сожалению, поскольку UITextField не разрешает вызов метода insertText: protocol.

Может помочь вам в пути, хотя..

Ответ 8

Я решил это, подклассифицировав UITextField как NextableTextField. Этот подкласс имеет свойство класса UITextField с подключением IBOutlet.

Постройте интерфейс в IB. Установите класс текстового поля в NextableTextField. Используйте Инспектор соединений, чтобы перетащить соединение в поле "Далее", на которое вы хотите перейти.

В текстовом поле класса делегата добавьте этот метод делегата...

- (BOOL)textFieldShouldReturn:(UITextField *) textField
{
    BOOL didResign = [textField resignFirstResponder];
    if (!didResign) return NO;

    if ([textField isKindOfClass:[NextableTextField class]])
        dispatch_async(dispatch_get_current_queue(), ^{ [[(NextableTextField *)textField nextField] becomeFirstResponder]; });

    return YES;
}

Кстати - я не придумал этого; просто помните, что видели какую-то еще идею.