1

I want to move the screen upwards when I show the keyboard and move to the bottom when I hide the keyboard.

I use this code:

override func viewDidLoad() {
        super.viewDidLoad()

        NotificationCenter.default.addObserver(self, selector: #selector(ViewController.keyboardWillShow), name: NSNotification.Name.UIKeyboardWillShow, object: nil)
        NotificationCenter.default.addObserver(self, selector: #selector(ViewController.keyboardWillHide), name: NSNotification.Name.UIKeyboardWillHide, object: nil)

}

@objc func keyboardWillShow(notification: NSNotification) {
        if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue {
            if self.view.frame.origin.y == 0{
                self.view.frame.origin.y -= keyboardSize.height
            }
        }
    }

    @objc func keyboardWillHide(notification: NSNotification) {
        if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue {
            if self.view.frame.origin.y != 0{
                self.view.frame.origin.y += keyboardSize.height
            }
        }
    }

But I have this problem: http://gph.is/2AvLo1A

On this screen I tap on textField to show keyboard and tap on empty space to hide keyboard several times. My screen crawls down, and the black background fills the entire screen. How to fix it?

Update:

http://gph.is/2F7nux5

After shown the keyboard I have new empty space at the bottom. And if I scroll I can see it: https://i.stack.imgur.com/hTXag.jpg

Eric Aya
  • 69,473
  • 35
  • 181
  • 253
user
  • 87
  • 1
  • 8

2 Answers2

1

Hook the bottom constraint of the scrollview to the superViews's bottom and drag it as IBOutlet and do this

 @objc func keyboardWillShow(notification: NSNotification) {
    if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue {

          self.scrollviewBottomCon.constant = keyboardSize.height
          self.view.layoutIfNeeded()
          self.scrollView.scrollRectToVisible((self.textfeild.frame), animated: true)
    }
}

@objc func keyboardWillHide(notification: NSNotification) {
    if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue {

            self.scrollviewBottomCon.constant = 0

            self.view.layoutIfNeeded()
    }
}
Shehata Gamal
  • 98,760
  • 8
  • 65
  • 87
  • My keyboard cover textField in this case. But after several showing of keyboard I have many empty space at the bottom. – user Jan 05 '18 at 15:50
  • is this view the main view controller view or a subview in it – Shehata Gamal Jan 05 '18 at 15:52
  • try to make the textfeild up and down not it's parent view – Shehata Gamal Jan 05 '18 at 15:54
  • View --> Scroll View --> Content View --> my content – user Jan 05 '18 at 15:54
  • Content move upwards on several pixel but also keyboard covet the textField. – user Jan 05 '18 at 16:05
  • does that textfeild at the very bottom of the scrollview's contentview ??? – Shehata Gamal Jan 05 '18 at 16:08
  • Yes, I move textfeild down on storyboard to check it. – user Jan 05 '18 at 16:11
  • In this case textField not move upwards. But it conversely move under keyboard. – user Jan 05 '18 at 19:12
  • it really depends who is the first item in the constraint make it self.scrollviewBottomCon.constant = keyboardSize.height instead of the negative to reverse the direction – Shehata Gamal Jan 05 '18 at 19:39
  • I trying but in this case after the keyboard showing I have a lot of empty space under textField and if I scroll down I can see textField above the keyboard. But it does not work automatically. – user Jan 05 '18 at 20:04
  • post a photo of the initial look of the view with the textfeild when keyboard is hidden and i will guide you – Shehata Gamal Jan 05 '18 at 23:25
  • Have you looked at the new screens? – user Jan 06 '18 at 14:42
  • Empty space appears at the bottom after displaying the keyboard. – user Jan 06 '18 at 15:29
  • Yes. Did you try to test your code in the project? Could you give me an example project if you have it. It would be much easier for me to understand and accept your answer. – user Jan 06 '18 at 17:36
  • you tried my answer ? i see from you image that you have a multiline label below it a textfeild and below is a button , when the keyboard is shown the bottom of the scrollview is shifted up by the height of the keyboard and when the keyboard ts hidden the bottom of the scrollview is restored to it's initial position then where is you problem – Shehata Gamal Jan 06 '18 at 17:57
  • The problem is that the scrollview does not automatically scroll. The first gif shows how I will scroll to the end of the screen and call the keyboard that cover textfield. On the 2nd picture, if I scroll after calling the keyboard down then textfield does not cover. The problem is that I need to scroll manually after calling the keyboard. But this scroll should work automatically. – user Jan 09 '18 at 07:42
  • Do you understand my problem? What I should do? – user Jan 10 '18 at 08:22
  • send me a demo of that screen only and I will fix it for you' – Shehata Gamal Jan 10 '18 at 08:26
  • https://stackoverflow.com/questions/49670145/autoayout-issue-swift-3-0 @Sh_Khan need help for this question – Dilip Tiwari Apr 05 '18 at 11:58
  • @Sh_Khan I understand this is not welcomed by the community. But could you please help with this problem. I just don't know what to do. Thanks! - https://stackoverflow.com/questions/69851479/audio-files-wont-play-with-airpods-pro-on-ios-15 – user Nov 12 '21 at 20:36
0

Try not to move the entire view up and down, rather the components you really need to move. I'd suggest using a view to contain the elements you want to move.

I have a use case where I have a coupe text fields and a submit button beneath in a container view. When the keyboard appears, I wanted the two text fields and button to rise. Here's how I handled that.

@objc func keyboardWillAppear(_ notification: NSNotification) {
    if let userInfo = notification.userInfo,
        let keyboardFrame = (userInfo[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue {

        // Calculate how much to move
        let submitButtonHeight = self.submitButton.frame.size.height
        var submitButtonOrigin = self.view.convert(self.submitButton.frame.origin, from: self.containerView)
        submitButtonOrigin.y = submitButtonOrigin.y + submitButtonHeight + 4.0
        var visibleRect = self.view.frame
        visibleRect.size.height -= keyboardFrame.height

        // If keyboard covers the button, move the container up
        if !visibleRect.contains(submitButtonOrigin) {
            let keyboardMove = submitButtonOrigin.y - visibleRect.size.height
            if keyboardMove > 0 {
                UIView.animate(withDuration: 0.3) {
                    self.containerView.transform = CGAffineTransform(translationX: 0, y: -keyboardMove)
                }
            }
        }
    }
}

@objc func keyboardWillDisappear(_ notification: NSNotification) {
    UIView.animate(withDuration: 0.3) {
        self.containerView.transform = CGAffineTransform.identity
    }
}

This may or may not be a solution for you, but can provide another option.

Derek
  • 1,011
  • 6
  • 17