0

Below is the code that I'm trying to use to have the view scroll only when the focused textField or UIButton is hidden by the keyboard:

import UIKit

class ViewController: UIViewController, UITextFieldDelegate {

    @IBOutlet weak var buttonToBottomConstraint: NSLayoutConstraint!

    @IBOutlet weak var textFieldUsername: UITextField!
    @IBOutlet weak var textFieldPassword: UITextField!
    @IBOutlet weak var scrollView: UIScrollView!


    override func viewDidLoad() {
        super.viewDidLoad()

        NSNotificationCenter.defaultCenter().addObserver(self, selector:"keyboardWillBeHidden:", name: UIKeyboardWillHideNotification, object: nil)

        NSNotificationCenter.defaultCenter().addObserver(self, selector:"keyboardWillBeShown:", name: UIKeyboardWillShowNotification, object: nil)
    }

    func textFieldDidBeginEditing(textField: UITextField) {
    }

    func textFieldShouldReturn(textField: UITextField) -> Bool {textField.resignFirstResponder()

        return true
    }

    func keyboardWillBeHidden(notification: NSNotification){

        self.scrollView.setContentOffset(CGPointMake(0, 0), animated: true)
    }

    func keyboardWillBeShown(notification: NSNotification){

        let userInfo = notification.userInfo!

        if let kbsize = userInfo[UIKeyboardFrameBeginUserInfoKey]?.CGRectValue().size{

             self.scrollView .setContentOffset(CGPointMake(0, kbsize.or), animated: true)
        }
    }
}

Problem: The View scrolls even when the keyboard is not hiding anything.

View at Launch:

enter image description here

View Upon Tapping on a TextField:

enter image description here

Question: How do I check to see if the focused field is hidden by the keyboard, and ONLY if it is, push it above it?

Project: TextFieldScroll

EDIT

App works fine in Portrait mode, however, not in landscape mode. Also in landscape mode, when the Username textField keyboard is up and I tap the Password textField, it remains hidden behind the keyboard. I updated the project on Github and fixed the link. Thanks

Screen shot in landscape:

enter image description here

user1107173
  • 10,334
  • 16
  • 72
  • 117

2 Answers2

1
var currentTextField:UITextField?

@IBOutlet weak var textFieldUsername: UITextField!
@IBOutlet weak var textFieldPassword: UITextField!
@IBOutlet weak var scrollView: UIScrollView!


override func viewDidLoad() 
{
    super.viewDidLoad()

    NSNotificationCenter.defaultCenter().addObserver(self, selector:"keyboardWillBeHidden:", name: UIKeyboardWillHideNotification, object: nil)

    NSNotificationCenter.defaultCenter().addObserver(self, selector:"keyboardWillBeShown:", name: UIKeyboardWillShowNotification, object: nil)
}

func textFieldDidBeginEditing(textField: UITextField)
{
currentTextField=textField;
}

func textFieldShouldReturn(textField: UITextField) -> Bool {
textField.resignFirstResponder()

    return true
}

func keyboardWillBeHidden(notification: NSNotification){
      currentTextField=nil;
    self.scrollView.setContentOffset(CGPointMake(0, 0), animated: true)
}

func keyboardWillBeShown(notification: NSNotification){

    let userInfo = notification.userInfo!

    if let kbsize = userInfo[UIKeyboardFrameBeginUserInfoKey]?.CGRectValue().size
    {
          let contentInsets = UIEdgeInsets(top: 0, left: 0, bottom: kbsize.height, right: 0)
        let screenSize: CGRect = UIScreen.mainScreen().bounds
       let screenHeight = screenSize.height
        let height:CGFloat=screenHeight-(kbsize.height)-(currentTextField!.frame.size.width)

         if(currentTextField!.frame.origin.y>=height )
        {
            var scrollPoint: CGPoint  = CGPointMake(0.0, currentTextField!.frame.origin.y - (kbsize.height));
            self.scrollView .setContentOffset(scrollPoint, animated: true)
        }

    }
}

  func textFieldDidEndEditing(textField: UITextField) {
     currentTextField=nil;
   }
Jincy Sam
  • 421
  • 2
  • 11
0

I don't see you setting the scrollView's contentSize. Thus, the scrollView scrolls with the keyboard since it uses the screen's size.

saagarjha
  • 2,221
  • 1
  • 20
  • 37
  • What should be the content size? or where should I set it? – user1107173 Aug 18 '15 at 04:10
  • When you use a `UIScrollView`, you need to tell it how large your content will be. You should set its `contentSize` to tell it this ASAP (`viewDidLoad` or `didSet`, for example). You need to pass in a `CGSize`, which accepts the width and the height. The width will be the width of the view controller, and the height will be the height of the logo+label+text fields+button+the space in between. – saagarjha Aug 18 '15 at 04:32
  • Thanks. Nothing happens when I add to content size in `viewDidLoad` – user1107173 Aug 18 '15 at 04:36
  • I added the following line `self.scrollView.contentSize = CGSize(width: self.view.frame.width, height: CGFloat(400))`, the result is the same as the 2nd image. – user1107173 Aug 18 '15 at 04:42
  • Also, I used IB to add `scrollView` and it covers the entire screen. – user1107173 Aug 18 '15 at 04:46