2015-10-13 2 views
2

У меня есть UIToolbar с TextField и Button как UIBarButtonItem. Я пытаюсь использовать эту панель инструментов как входную функцию для клавиатуры, когда пользователь нажимает TextField внутри панели инструментов.Создание UIToolbar с TextField вверх с клавиатурой

enter image description here

Я нашел this question, который пытается решить ту же проблему. К сожалению, решение не было эффективным.

Что я пытаюсь это:

class ChatViewController: UIViewController, CLLocationManagerDelegate, UITableViewDelegate, UITableViewDataSource { 

    @IBOutlet weak var chatTableView: UITableView! 
    @IBOutlet weak var chatToolbar: UIToolbar! 

    @IBOutlet weak var textFieldBarButtonItem: UIBarButtonItem! 

    override func viewDidAppear(animated: Bool) { 
     super.viewDidLoad() 
     self.chatTableView.delegate = self 
     self.chatTableView.dataSource = self 
     self.chatToolbar.removeFromSuperview() 

    } 

    override var inputAccessoryView: UIView{ 
     get{ 
      return self.chatToolbar 
     } 
    } 

    override func canBecomeFirstResponder() -> Bool { 
     return true 
    } 

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell{ 

     let cell = UITableViewCell() 
     return cell 
    } 

    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 

     return 0 
    } 

} 

И что я получаю обратно есть:

*** Terminating app due to uncaught exception 'UIViewControllerHierarchyInconsistency', reason: 
'child view controller:<UICompatibilityInputViewController: 0x13ff34e00> should have parent view controller: 
<App.ChatViewController: 0x13ff21cc0> but requested parent is:<UIInputWindowController: 0x1400b4600>' 

Любые идеи?

+0

Это не плохой подход, проблема должна заключаться в том, что 'inputAccessoryView:' вызывается перед 'viewDidAppear'. Аксессуарный вид не должен принадлежать ни одной иерархии представлений. BTW: принятый ответ тоже нормально – Omer

+0

@Omer Отлично, и что вы предлагаете? – adolfosrs

+1

Я думаю, что оба подхода прекрасны, я предпочитаю аксессуарInputView, потому что он более чист между другими преимуществами (то есть: более простой способ использования 'UIScrollViewKeyboardDismissModeInteractive', независимой от раскадровки/xib, безумного ограничения без ограничений = D). Следующая ссылка содержит obj-c proj с базовой реализацией с использованием вспомогательного метода просмотра, который вы можете развить на всякий случай, если хотите попробовать: https://www.dropbox.com/s/a4bsvz0ie95i3qn/KeyboardAccessory.zip? dl = 0 ||| не я использую панель инструментов, но вы можете использовать любой подкласс UIView, который вы хотите – Omer

ответ

10

Первые вещи сначала:

  1. Вы должны создавать ограничения на панель инструментов в раскадровке (слева, снизу, справа).
  2. Создайте розетку для вашего нижнего ограничения в вашем контроллере вида (перетащите из раскадровки). Сохранить начальное значение ограничения (для восстановления, когда клавиатура исчезает)
  3. Создания наблюдателя, чтобы знать, когда ваша клавиатура появляется и исчезает (3.1 и создать водопроводный жест, чтобы скрыть клавиатуру)
  4. Когда клавиатура 4.1 появится и 4.2 исчезает, вы будете только изменить значение нижнего ограничения (размер клавиатуры). Вы также можете анимировать панель инструментов.

Что-то вроде:

class ChatViewController: UIViewController, CLLocationManagerDelegate, UITableViewDelegate, UITableViewDataSource { 

    @IBOutlet weak var chatTableView: UITableView! 
    @IBOutlet weak var chatToolbar: UIToolbar! 

    @IBOutlet weak var textFieldBarButtonItem: UIBarButtonItem! 

    //2 
    @IBOutlet weak var toolbarBottomConstraint: NSLayoutConstraint! 
    var toolbarBottomConstraintInitialValue: CGFloat? 

    override func viewDidAppear(animated: Bool) { 
     super.viewDidAppear(animated) 
     self.chatTableView.delegate = self 
     self.chatTableView.dataSource = self 
     self.chatToolbar.removeFromSuperview() 

     //2 
     self.toolbarBottomConstraintInitialValue = toolbarBottomConstraint.constant 
     //3 
     enableKeyboardHideOnTap() 

    } 

    // 3 
    // Add a gesture on the view controller to close keyboard when tapped 
    private func enableKeyboardHideOnTap(){ 

     NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("keyboardWillShow:"), name: UIKeyboardWillShowNotification, object: nil) // See 4.1 
     NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("keyboardWillHide:"), name: UIKeyboardWillHideNotification, object: nil) //See 4.2    

     // 3.1 
     let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: "hideKeyboard") 

     self.view.addGestureRecognizer(tap) 
    } 

    //3.1 
    func hideKeyboard() { 
     self.view.endEditing(true) 
    } 

    //4.1 
    func keyboardWillShow(notification: NSNotification) { 

     let info = notification.userInfo! 

     let keyboardFrame: CGRect = (info[UIKeyboardFrameEndUserInfoKey] as! NSValue).CGRectValue() 

     let duration = notification.userInfo![UIKeyboardAnimationDurationUserInfoKey] as! Double   

     UIView.animateWithDuration(duration) {() -> Void in 

      self.toolbarBottomConstraint.constant = keyboardFrame.size.height + 5 

      self.view.layoutIfNeeded() 

     } 

    } 

    //4.2 
    func keyboardWillHide(notification: NSNotification) { 

     let duration = notification.userInfo![UIKeyboardAnimationDurationUserInfoKey] as! Double 

     UIView.animateWithDuration(duration) {() -> Void in 

      self.toolbarBottomConstraint.constant = self.toolbarBottomConstraintInitialValue! 
      self.view.layoutIfNeeded() 

     } 

    } 

    override var inputAccessoryView: UIView{ 
     get{ 
      return self.chatToolbar 
     } 
    } 

    override func canBecomeFirstResponder() -> Bool { 
     return true 
    } 

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell{ 

     let cell = UITableViewCell() 
     return cell 
    } 

    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 

     return 0 
    } 

} 

Надеется, что это помогает!

+0

работал как шарм. У мужчины. – adolfosrs

+0

работал отлично! –