1

i have a log in page and for smaller screens (for example iPhone 4s) keyboard can overlay on login button and password textfield etc. So i placed username textfield, password textfield and login button into a UIView which is connected to the ViewController as loginView, and I want to detect if keyboard is on loginView ,it'll push loginView and not overlay on it, and pushing will stop when keyboard is fully open, so loginView will stand just on keyboard. And when keyboard is closed, it'll pull loginView until it reaches its first position.

I tried this but i' pushes all view

var kbHeight: CGFloat!

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

func animateTextField(up: Bool) {
    var movement = (up ? -kbHeight : kbHeight)

    UIView.animateWithDuration(0.3, animations: {
        self.view.frame = CGRectOffset(self.view.frame, 0, movement)
    })

}

func keyboardWillShow(notification: NSNotification) {

    if let userInfo = notification.userInfo {
        if let keyboardSize =  (userInfo[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.CGRectValue() {
            kbHeight = keyboardSize.height
            self.animateTextField(true)
        }
    }

}

func keyboardWillHide(notification: NSNotification) {

    self.animateTextField(false)

}

this is the sample i found in many website that people have same problem with me are using this. I changed this self.view.frame = CGRectOffset(self.view.frame, 0, movement) line with self.loginView.frame = CGRectOffset(self.view.frame, 0, movement) becausei want to push my loginView View which has textfields and buttons inside it, but it still dont work and cover login button, so not push properly. I'd be glad if someone can explain me how to do it or show me a source that explains it, i searched but couldnt find, maybe i missed.

Here is my UI http://i62.tinypic.com/1bssy.png

Thanks in advice

marmaralone
  • 516
  • 6
  • 11

2 Answers2

3

Make following change in your code

Replace this

    func keyboardWillShow(notification: NSNotification) {

        if let userInfo = notification.userInfo {
            if let keyboardSize =  (userInfo[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.CGRectValue() {
            kbHeight = keyboardSize.height
                self.animateTextField(true)
            }
        }
    }

with

    func keyboardWillShow(notification : NSNotification) {

        var keyboardInfo : NSDictionary = notification.userInfo!

        var kbSize : CGSize = ((keyboardInfo.objectForKey(UIKeyboardFrameEndUserInfoKey)) as! CGRect).size


        var durationValue : NSNumber = keyboardInfo[UIKeyboardAnimationDurationUserInfoKey] as! NSNumber
        var animationDuration : NSTimeInterval = durationValue.doubleValue

        let rawAnimationCurveValue = (keyboardInfo[UIKeyboardAnimationCurveUserInfoKey] as! NSNumber).unsignedIntegerValue
        let keyboardAnimationCurve = UIViewAnimationCurve(rawValue: rawAnimationCurveValue)

        let options = UIViewAnimationOptions(UInt((keyboardInfo[UIKeyboardAnimationCurveUserInfoKey] as! NSNumber).integerValue << 16))

        UIView.animateWithDuration(animationDuration, delay: 0, options:options , animations: { () -> Void in

            self.loginView.frame = CGRectMake(self.loginView.frame.origin.x, self.loginView.frame.origin.y - kbSize.height, self.loginView.frame.size.width, self.loginView.frame.size.height)

        }, completion: nil)
    }

And

This

func keyboardWillHide(notification: NSNotification) {

    self.animateTextField(false)

}

with

    func keyboardWillHide(notification : NSNotification) {

        var keyboardInfo : NSDictionary = notification.userInfo!

        var kbSize : CGSize = ((keyboardInfo.objectForKey(UIKeyboardFrameEndUserInfoKey)) as! CGRect).size


        var durationValue : NSNumber = keyboardInfo[UIKeyboardAnimationDurationUserInfoKey] as! NSNumber
        var animationDuration : NSTimeInterval = durationValue.doubleValue

        let rawAnimationCurveValue = (keyboardInfo[UIKeyboardAnimationCurveUserInfoKey] as! NSNumber).unsignedIntegerValue
        let keyboardAnimationCurve = UIViewAnimationCurve(rawValue: rawAnimationCurveValue)

        let options = UIViewAnimationOptions(UInt((keyboardInfo[UIKeyboardAnimationCurveUserInfoKey] as! NSNumber).integerValue << 16))

        UIView.animateWithDuration(animationDuration, delay: 0, options:options , animations: { () -> Void in

            self.loginView.frame = CGRectMake(self.loginView.frame.origin.x, self.loginView.frame.origin.y + kbSize.height, self.loginView.frame.size.width, self.loginView.frame.size.height)

        }, completion: nil)
    }
Ashish P.
  • 848
  • 5
  • 12
  • first of all thank you so much for your answer, it helped me a lot. I answered your post but i was so long so i post it as a new answer, so please check my post up :) – marmaralone Jul 27 '15 at 08:29
  • I checked your post. See my updated answer if you need to set animation in keyboard will appear method. – Ashish P. Jul 27 '15 at 09:30
  • it didnt work. We need to update kbSize simultaneously, not set it as CGSize = ((keyboardInfo.objectForKey(UIKeyboardFrameEndUserInfoKey)) as! CGRect).size (i changed this line like this because "CGSize = ((keyboardInfo.objectForKey(UIKeyboardFrameEndUserInfoKey)) as! CGRect).size" gives error)because it gives it a fixed value, but it changes from 0 to 216, in 0,25 second, so while it changes, we need to change kbSize too I think. What do you think? – marmaralone Jul 27 '15 at 10:03
  • "We need to update kbSize simultaneously" I didn't get it? why we need to update. keyboardWillShow notification will fire only once when keyboard is ready to appear. Is there any runtime error in above code, let me know as I have not tested above code. – Ashish P. Jul 27 '15 at 11:01
  • At the end of the animation, UIView stops where was stands before animation, not sit on the keyboard. when keyboard starts to show, UIview goes down and start animation with keyboard, going up, and then stands where was before animation, half of UIView still under the keyboard. This is the problem :) thats because i said maybe we need to update keyboard height but its irrelevant i just understand that its not necessary as you said, what could it be the problem that UIView is still under the keyboard after animation finish? im out of solution :) – marmaralone Jul 27 '15 at 11:17
  • 1
    I used TPkeyboardavoidingscrollview instead of trying to solve this ;) thank you for your support, at least i understand the logic, even if i couldnt solve the problem :) – marmaralone Jul 27 '15 at 12:24
0

It didnt work well but your answer gives me an opinion. this works, but it works when keyboard is completely open, so its not animating :)

    func animateTextField(up: Bool) {

    var movement = (up ? -kbHeight : kbHeight)

    UIView.animateWithDuration(0.3, animations: {

        if (up == true) {

            self.loginView.frame = CGRectMake(self.loginView.frame.origin.x, self.loginView.frame.origin.y - self.kbHeight, self.loginView.frame.size.width, self.loginView.frame.size.height)
        } else {

            self.loginView.frame = CGRectMake(self.loginView.frame.origin.x, self.loginView.frame.origin.y + self.kbHeight, self.loginView.frame.size.width, self.loginView.frame.size.height)
        }
    })
}

func keyboardWillHide(notification: NSNotification) {

    self.animateTextField(false)

}

func keyboardDidShow(notification: NSNotification) {

    if let userInfo = notification.userInfo {

        if let keyboardSize =  (userInfo[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.CGRectValue() {
            kbHeight = keyboardSize.height - self.loginView.frame.size.height
            self.animateTextField(true)
        }
    }
}

when i put a breakpoint on userInfo line, i get this

[UIKeyboardFrameBeginUserInfoKey: NSRect: {{0, 480}, {320, 216}}, UIKeyboardCenterBeginUserInfoKey: NSPoint: {160, 588}, UIKeyboardFrameEndUserInfoKey: NSRect: {{0, 264}, {320, 216}}, UIKeyboardCenterEndUserInfoKey: NSPoint: {160, 372}, UIKeyboardAnimationDurationUserInfoKey: 0.25, UIKeyboardBoundsUserInfoKey: NSRect: {{0, 0}, {320, 216}}, UIKeyboardAnimationCurveUserInfoKey: 7]

How can i start animation in keyboardWillShow function and use keyboard opening animation. I mean keyboard will start to show, and when it reaches the edge of the view, it'll start pushing. I need to do it in keyboardWillShow function because keyboardDidShow works but not push the view simultaneously

marmaralone
  • 516
  • 6
  • 11