2016-05-20 3 views
3

Я сделал приложение для калькулятора (swift), и я настроил некоторые UIKeyCommands, чтобы, если у пользователя есть клавиатура Bluetooth, они могут вводить цифры/символы в калькулятор ,UIKeyCommand не отключен при вводе текста в текстовое поле (Swift)

Они работают так:

UIKeyCommand(input: "4", modifierFlags: [], action: "TypeFourInCalculator:") 
func TypeFourInCalculator(sender: UIKeyCommand) { 
    btn4Press(UIButton) 
} 

Это все работало хорошо, добавив четыре в калькулятор, когда пользователь нажал на четыре ключа (даже если сам калькулятор не имеет текстового поля). Тем не менее: у меня также есть несколько стандартных текстовых полей, и я хочу, чтобы UIKeyCommands останавливались, когда пользователь входит в одно из этих текстовых полей (так что они могут снова набирать клавиатуру BT снова). Без отключения UIKeyCommands, ввода результатов в функции калькулятора и ввода текста в текстовое поле.

Так что я попытался это в попытке отключить UIKeyCommands, когда текстовое поле становится первым ответчиком:

let globalKeyCommands = [UIKeyCommand(input: "4", modifierFlags: [], action: "TypeFourInCalculator:"), UIKeyCommand(input: "5", modifierFlags: [], action: "TypeFiveInCalculator:")] 

override var keyCommands: [UIKeyCommand]? { 
    if powertextfield.isFirstResponder() == false { // if the user isn't typing into that text field 
     return globalKeyCommands // use key commands 
    } else { // if the user is typing 
     return nil // disable those UIKeyCommands 
    } 

Это работает, но иногда все же часто не работает. Если пользователь еще ничего не набрал с помощью клавиатуры BT (т. Е. Не активировал команды клавиш, я думаю), они могут набирать клавиатуру BT, как обычно, в текстовое поле. Но если они уже вводили числа в калькулятор через UIKeyCommand, они не могут вводить текстовое поле (ну, иногда оно работает с нормальным поведением, иногда оно терпит неудачу, как и до того, как я добавил этот предупредительный код). Типированный текст просто не отображается в этом текстовом поле, и вместо этого он просто вызывает команду калькулятора.

Итак, что я могу сделать, чтобы отключить эти UIKeyCommands, когда пользователь начинает вводить в обычном текстовом поле?

+0

Я бы использовал некоторую регистрацию, чтобы узнать, когда запрашивается 'keyCommands', чтобы убедиться, что она обновляется, когда вы думаете, что она обновляется. – sschale

+0

Ответ ниже был действительно полезным, поэтому благодарит Криса. Если кто-то останавливается здесь, нужна какая-либо помощь, просто напишите ниже, и я могу вам помочь. – owlswipe

ответ

2

Вместо того, чтобы keyCommands вычисляемый свойство можно использовать addKeyCommand(_:) и removeKeyCommand(_:) методы UIViewController с. Подкласс вашего текстового поля, как это:

class PowerTextField: UITextField { 
    var enableKeyCommands: (Bool->())? 

    override func becomeFirstResponder() -> Bool { 
     super.becomeFirstResponder() 
     enableKeyCommands?(false) 
     return true 
    } 

    override func resignFirstResponder() -> Bool { 
     super.resignFirstResponder() 
     enableKeyCommands?(true) 
     return true 
    } 
} 

Тогда в вашем UIViewController:

override func viewDidLoad() { 
    super.viewDidLoad() 

    // globalKeyCommands is a view controller property 

    // Add key commands to be on by default 
    for command in globalKeyCommands { 
     self.addKeyCommand(command) 
    } 

    // Configure text field to callback when 
    // it should enable key commands 
    powerTextField.enableKeyCommands = { [weak self] enabled in 
     guard let commands = self?.globalKeyCommands else { 
      return 
     } 
     if enabled { 
      for command in globalKeyCommands { 
       self?.addKeyCommand(command) 
      } 
     } else { 
      for command in globalKeyCommands { 
       self?.removeKeyCommand(command) 
      } 
     } 
    } 
} 

Вместо необязательного хранимой процедуры, которая получает сконфигурированной UIViewController, вы могли бы настроить протокол делегата для UITextField, что UIViewController будет принят.

Кроме того, если вам нужно, чтобы остановить эти ключевые команды, когда UIAlertController всплывает, вы можете сделать подкласс UIAlertController, который реализует viewWillAppear(_:) и viewWillDisappear(_:) событий методы, аналогичные тем, как вы реализовали becomeFirstResponder() и resignFirstResponder(), путем вызова enableKeyCommands(_:) необязательно хранить процедура, настроенная вашим основным контроллером просмотра во время его viewDidLoad().

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

+0

Где я могу поместить этот второй блок кода? Если я просто поместил его в любом месте моего UIViewController, он говорит «Ошибка: ожидаемая декларация». – owlswipe

+0

@JohnRamos есть несколько мест, которые вы можете поместить, которые могут иметь смысл в зависимости от вашего приложения, но я предполагаю, что вы, вероятно, должны поместить его в viewDidLoad() –

+0

Итак, я положил первый блок кода прямо внизу мой контрольный файл просмотра калькулятора, внутри моего класса UIViewController, но не внутри ничего другого, а второй блок кода внутри viewdidload и весь мой другой код UIKeyCommand внутри viewdidload, а моя сборка проекта завершилась неудачей с ошибкой «Segmentation Fault 11.» – owlswipe

Смежные вопросы