0

OK, so I am trying to implement an add comment box in my view. Here is the layout:

I have a UITabBarController containing a UINavigationController where my UIViewController is pushed to. The View Layout consists of a UITableView and a custom UIView that contains a UITextView and a UIButton.

I am monitoring for keyboard notifications, this is the code I have:

override func viewDidAppear(animated: Bool) {
    NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(keyboardWillAppear), name: UIKeyboardWillShowNotification, object: nil)
    NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(keyboardWillDisappear), name: UIKeyboardWillHideNotification, object: nil)
}

override func viewDidDisappear(animated: Bool) {
    NSNotificationCenter.defaultCenter().removeObserver(self)

}

func keyboardWillAppear(notification: NSNotification){
    if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.CGRectValue() {
        var frame = inputPanel.frame
        frame.origin.y = self.view.frame.height - (keyboardSize.height + inputPanel.frame.size.height)
        inputPanel.frame = frame
    }
}

func keyboardWillDisappear(notification: NSNotification){
    var frame = inputPanel.frame
    frame.origin.y = self.view.frame.height - inputPanel.frame.size.height
    inputPanel.frame = frame
}

When the keyboard displays, I have set breakpoints and see that the y coordinate is updated, but my view stays where it is, hidden behind the keyboard.

A couple of notes. I am using IQKeyboardManager and have disabled distance handling for this class. I am also using PureLayout for laying out the controls inside of the custom UIView. I am not setting any constraints for the custom UIView in the view controller. The positions of the UITableView and the custom UIView are set in the viewWillLayoutSubview method as below:

override func viewWillLayoutSubviews() {
    let y = self.view.frame.height - 44
    self.tableView.frame = CGRectMake(0, 0, self.view.frame.width, y)
    self.inputPanel.frame = CGRectMake(0, y, self.view.frame.width, 44)
}

On another note, this is working perfectly in another view I have that is not a child of a UINavigationController.

Screen shots of what is happening:

The view with the input view:

view with the input view

When the keyboard is shown:

keyboard is shown

Any help is greatly appreciated.

hawkstrider
  • 4,141
  • 16
  • 27

3 Answers3

1

For the views you are not applying constraints to, you need to tell the auto layout engine that you're going to use frames prior to setting their frame. You can do this by setting translatesAutoresizingMaskIntoConstraints to true. For example:

override func viewWillLayoutSubviews() {
    let y = self.view.frame.height - 44
    self.tableView.translatesAutoresizingMaskIntoConstraints = true
    self.tableView.frame = CGRectMake(0, 0, self.view.frame.width, y)
    self.inputPanel.translatesAutoresizingMaskIntoConstraints = true
    self.inputPanel.frame = CGRectMake(0, y, self.view.frame.width, 44)
}
beyowulf
  • 15,101
  • 2
  • 34
  • 40
  • I tried adding this in to no avail. I am not using any storyboard or xib, all of my views are created programatically. When I switched to the viewDidLayoutSubviews method, the lower panel didn't even show up in the view – hawkstrider Apr 25 '16 at 00:17
  • You might want to post the code of the tableView and inputPanel's initialization. Also are you sure keyboardWillAppear is getting called? Is it going into your if block? – beyowulf Apr 25 '16 at 02:16
  • It is definitely getting called. I have stepped through the code in there and see the origin.y value being changed, but the view does not move up. I am starting to think this may be an issue related to using PureLayout inside the custom view. – hawkstrider Apr 25 '16 at 21:29
  • Have you tried commenting it out and seeing what happens? – beyowulf Apr 26 '16 at 01:21
  • I have. I did some tests with a plain UIView and it works with that so must be something happening in the custom view. – hawkstrider Apr 26 '16 at 01:22
0

Try to remove this code from viewWillLayoutSubviews to viewDidLoad function

override func viewDidLoad() {
    super.viewDidLoad()

    let y = self.view.frame.height - 44
    self.tableView.frame = CGRectMake(0, 0, self.view.frame.width, y)
    self.inputPanel.frame = CGRectMake(0, y, self.view.frame.width, 44)
}

I guess viewWillLayoutSubviews function have been called after keyboard did appear event.

Evgeny Karkan
  • 8,782
  • 2
  • 32
  • 38
0

Try using UIKeyboardFrameEndUserInfoKey in place of UIKeyboardFrameBeginUserInfoKey

Bhavuk Jain
  • 2,167
  • 1
  • 15
  • 23