Search code examples
iosswiftkeyboardnsnotification

iOS keyboardWasShown, NSNotification and Optional issue


Sometimes I feel so lost in the world of iOS code. It's telling me it's not unwrapped it should have a "!". When I fix it, it's telling me it's wrong and to delete the "!". So I keep going in a loop. I can't for the life of me figure out what is wrong with this piece of code:

let keyboardSize: CGSize = info.objectForKey(UIKeyboardFrameEndUserInfoKey)?.frame.size

Here is the full code:

func keyboardWasShown(notification: NSNotification) -> Void {

    let info: NSDictionary = notification.userInfo!

    let keyboardSize: CGSize = info.objectForKey(UIKeyboardFrameEndUserInfoKey)?.frame.size

    let buttonOrigin: CGPoint = self.clearAllButton.frame.origin

    let buttonHeight: CGFloat = self.clearAllButton.frame.size.height

    let visibleRect: CGRect = self.view.frame

    visibleRect.size.height -= CGFloat(keyboardSize.height) as CGFloat

    if (!CGRectContainsPoint(visibleRect, buttonOrigin)){

        let scrollPoint: CGPoint = CGPointMake(0.0, buttonOrigin.y - visibleRect.size.height + buttonHeight)

        self.scrollView.setContentOffset(scrollPoint, animated: true)

    }


}

Solution

  • Your keyboardSize constant has type of CGSize and value that you are giving to it info.objectForKey(UIKeyboardFrameEndUserInfoKey)?.frame.size may return nil so you must declare your constant type as CGSize optional let keyboardSize: CGSize? = ...

    EDITED

    Since you are using keyboard size for calculating visible rect you full code should be like the following

    func keyboardWasShown(notification: NSNotification) -> Void {
    
    let info: NSDictionary = notification.userInfo!
    
    if let keyboardSize: CGSize = info.objectForKey(UIKeyboardFrameEndUserInfoKey)?.frame.size {
    
        let buttonOrigin: CGPoint = self.clearAllButton.frame.origin
    
        let buttonHeight: CGFloat = self.clearAllButton.frame.size.height
    
        let visibleRect: CGRect = self.view.frame
    
        visibleRect.size.height -= CGFloat(keyboardSize.height) as CGFloat
    
        if (!CGRectContainsPoint(visibleRect, buttonOrigin)){
    
            let scrollPoint: CGPoint = CGPointMake(0.0, buttonOrigin.y - visibleRect.size.height + buttonHeight)
    
            self.scrollView.setContentOffset(scrollPoint, animated: true)
    
        }
    
        }
    
    }