pavel_s
pavel_s

Reputation: 505

Properly dismiss keyboard in swift for collectionView

I'm creating a simple messenger chat window, and i'm using UICollectionView for my bubble-messages. Now I want to setup the keyboard to show and hide properly. I used NSNotifications and created functions for keyboardWillShow: and keyboardWillHide: events. Also I setup keyboardDismissMode to Interactive for my CollectionView. So now, when I scroll up, and my keyboard is hiding (which caused by Interactive dismiss mode), i also got keyboardWillHide event, which resets my UIEdgeInsets. So basically after I scroll up and my keyboard is hidden my scrollView immediately goes to the bottom. My goal is to make it work like in iMessage.app, WhatsApp and etc. I will appreciate any help or advice!

Here's my code:

class ViewController: UIViewController {

   @IBOutlet weak var collectionView: UICollectionView!
   var customView: CustomView!

    override func viewDidLoad() {
       super.viewDidLoad()
       customView = CustomView(frame: CGRectMake(0, 0, UIScreen.mainScreen().bounds.width, 40.0))
       customView.textView!.delegate = self
       collectionView.scrollToBottom(true)
       collectionView.keyboardDismissMode = UIScrollViewKeyboardDismissMode.Interactive

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

    }

   override var inputAccessoryView: UIView! {
       get {
           if customView == nil {
               customView = CustomView()
           }
           return customView
          }
       }

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

   func keyboardWillShow(notification: NSNotification) {
        let userInfo = notification.userInfo ?? [:]
        let keyboardFrame = (userInfo[UIKeyboardFrameBeginUserInfoKey] as! NSValue).CGRectValue()
        let adjustmentHeight = (CGRectGetHeight(keyboardFrame) + CGRectGetHeight(customView.frame) )
        let contentInset:UIEdgeInsets
        if UIInterfaceOrientationIsPortrait(UIApplication.sharedApplication().statusBarOrientation) {
            contentInset = UIEdgeInsetsMake(0, 0, adjustmentHeight, 0)
        } else {
            contentInset = UIEdgeInsetsMake(0, 0, keyboardFrame.width, 0)
        }
        collectionView.contentInset = contentInset
        collectionView.scrollIndicatorInsets = contentInset
        collectionView.scrollToBottom(true)
  }

   func keyboardWillHide(notification: NSNotification) {
       collectionView.contentInset = UIEdgeInsetsZero
       collectionView.scrollIndicatorInsets = UIEdgeInsetsZero
   }



}

Upvotes: 3

Views: 3157

Answers (1)

alionthego
alionthego

Reputation: 9743

Your collectionView is scrolling to the bottom when you interactively dismiss the keyboard not because the UIEdgeInsets are being reset to zero but rather because in this configuration the keyboardWillShow method is being called again when you dismiss the keyboard interactively. Presumably because of the inputAccessoryView. To verify this put a println in your keyboardWillShow method and try it again. I wanted to say this as a comment rather than an answer but I only have 47 rep and need 50 to comment. But I think this information can be useful to you.

Upvotes: 2

Related Questions