1

Is there an elegant way to seamlessly move a UIView (i.e. a UIButton), that lives on the bottom of it's parent view, to a keyboard's inputAccessoryView?

I envision the keyboard to basically pick up the button and drag it up while it is sliding in. Please see the the mock-up below. Obviously, I'd like this to work the other way around as well.

I know how to do both separately, but I have no idea how to combine it. Anyone out there who did that before?

Thanks!

Illustration of the idea

Update: I forgot to mention that I'm mainly working in the context of UIScrollViews. While André's answer below works fine for ordinary views, it breaks when using it with scroll views.

flohei
  • 5,248
  • 10
  • 36
  • 61

1 Answers1

4

in this case you could ignore using the inputaccessoryview and instead adjust the sign in button's bottom constraint on keyboard notifications.

class ViewController: UIViewController {
  @IBOutlet weak var signInButtonBottomConstraint: NSLayoutConstraint!

  override func viewDidLoad() {
    super.viewDidLoad()

    NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("keyboardWillShow:"), name: UIKeyboardWillShowNotification, object: nil)
    NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("keyboardWillHide:"), name: UIKeyboardWillHideNotification, object: nil)
  }

  func keyboardWillShow(notification: NSNotification) {
    let userInfo = notification.userInfo!

    let animationDuration = userInfo[UIKeyboardAnimationDurationUserInfoKey] as! Double
    let keyboardEndFrame = (userInfo[UIKeyboardFrameEndUserInfoKey] as! NSValue).CGRectValue()

    signInButtonBottomConstraint.constant = keyboardEndFrame.height
    UIView.animateWithDuration(animationDuration) { () -> Void in
      self.view.layoutIfNeeded()
    }
  }

  func keyboardWillHide(notification: NSNotification) {
    let userInfo = notification.userInfo!

    let animationDuration = userInfo[UIKeyboardAnimationDurationUserInfoKey] as! Double

    signInButtonBottomConstraint.constant = 0.0
    UIView.animateWithDuration(animationDuration) { () -> Void in
      self.view.layoutIfNeeded()
    }
  }
}
André Slotta
  • 13,774
  • 2
  • 22
  • 34
  • Thank you for your reply, André! That works just fine as long as I use ordinary views. I forgot to mention in my post that I'm mainly use scroll views, in which case this approach does not work anymore. The button then scrolls with the content. – flohei Nov 12 '15 at 20:56
  • and what if you exclude the button from the scrollview? – André Slotta Nov 12 '15 at 20:57
  • Oh yeah, right. I think that would work. It would just let me scroll my content underneath the button when the keyboard is hidden. But I'm not sure that would be a problem. Will definitely try that tomorrow. I'll let you know how that went. Thanks again! – flohei Nov 12 '15 at 21:00
  • 1
    you can simply set your scrollviews bottom contentinset to be the height of the sign in button. :) – André Slotta Nov 12 '15 at 21:01