Monday, June 6, 2016

Changing View When Showing Keyboard

 
var keyboardIsShowing = false

override func viewDidAppear(_ animated: Bool) {  
    NotificationCenter.default.addObserver(self, selector: 
        #selector(keyboardDidShow), 
        name: Notification.Name.UIKeyboardDidShow, object: nil)
    NotificationCenter.default.addObserver(self, selector: 
        #selector(keyboardWillHide), 
        name: Notification.Name.UIKeyboardWillHide, object: nil)
}

override func viewWillDisappear(_ animated: Bool) {
    NotificationCenter.default.removeObserver(self, 
        name: Notification.Name.UIKeyboardDidShow, object: self)
    NotificationCenter.default.removeObserver(self, 
        name: Notification.Name.UIKeyboardWillHide, object: self)
}
 

Not In A Scroll View

 
@objc 
func keyboardDidShow(notification: NSNotification) {
    
    if keyboardIsShowing { return }
    
    let keyboardSize = (notification.userInfo![UIKeyboardFrameEndUserInfoKey] as! NSValue).cgRectValue.size
        
    keyBoardIsShowing = true
        
    var newFrame = self.view.frame
    newFrame.origin.y -= keyboardSize.height
    self.view.frame = newFrame
}

@objc 
func keyboardWillHide(notification: NSNotification) {
    let keyboardSize = (notification.userInfo![UIKeyboardFrameEndUserInfoKey] as! NSValue).cgRectValue.size
        
    keyboardIsShowing = false
        
    var newFrame = self.view.frame
    newFrame.origin.y += keyboardSize.height
}
 
Note: While this works fine, I always had trouble getting it to show smoothly or even animate it. It is choppy. As of this date I recommend just putting your view in a scroll view and using the below methods for a smoother look and feel.

In A Scroll View

 
@IBOutlet weak var scrollView: UIScrollView!

@objc 
func keyboardDidShow(notification: NSNotification) {
    
    if keyboardIsShowing { return }
    
    let keyboardSize = (notification.userInfo![UIKeyboardFrameEndUserInfoKey] as! NSValue).cgRectValue.size
        
    keyboardIsShowing = true
    
    let contentInsets = UIEdgeInsets(top: 0, left: 0, bottom: keyboardSize.height, right: 0)
    scrollView.contentInset = contentInsets
    scrollView.scrollIndicatorInsets = contentInsets

    // OPTIONAL: When you want bottom of a view to rest on the top of the keyboard.
    let viewBottom = myView.frame.origin.y + myView.frame.height
    let keyboardTop = view.bounds.height - keyboardSize.height

    if viewBottom > keyboardTop {
        let y = viewBottom - keyboardTop + 5
        scrollView.setContentOffset(CGPoint(x: 0, y: y), animated: true)
    }
}

@objc 
func keyboardWillHide(notification: NSNotification) {
    keyboardIsShowing = false

    let contentInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
    scrollView.contentInset = contentInsets
    scrollView.scrollIndicatorInsets = contentInsets
}
 

(Xcode 9, Swift 4)

No comments:

Post a Comment

Note: Only a member of this blog may post a comment.

SwiftUI Search & Filter with Combine - Part 3 (iOS, Xcode 13, SwiftUI, 2...

In part 3 of the Searchable video series, I show you how to use Combine in #SwiftUI for the search and filter logic connected to the searcha...