10

After trying out most of the solutions posted here, I'm still having trouble moving the textfield to show up above keyboard in a scrollview.

These are links I followed from Stackoverflow solutions: Link 1 Link 2 Link 3

I'm working on a signup screen that has 1 field behind the keyboard when it shows up.

Here's my code:

class SignUpViewController: UIViewController, UITextFieldDelegate, UIScrollViewDelegate, UIPopoverPresentationControllerDelegate {

@IBOutlet var firstNameTextField: UITextField!
@IBOutlet var lastNameTextField: UITextField!
@IBOutlet var phoneNumberTextField: UITextField!
@IBOutlet var emailTextField: UITextField!
@IBOutlet var submitButton: UIButton!
@IBOutlet var professionButton: UIButton!

var scrollView: UIScrollView?
var activeTextField:UITextField? = UITextField()

override func viewDidLoad() {
    super.viewDidLoad()

    let notificationCenter = NSNotificationCenter.defaultCenter()

    notificationCenter.addObserver(self, selector: #selector(SignUpViewController.keyboardWasShown(_:)), name: UIKeyboardWillShowNotification, object: nil)
    notificationCenter.addObserver(self, selector: #selector(SignUpViewController.keyboardWillBeHidden(_:)), name: UIKeyboardWillHideNotification, object: nil)
    scrollView = UIScrollView(frame: CGRect(x: 0, y: 0, width: self.view.frame.size.width, height: self.view.frame.size.height))
    scrollView!.contentSize = CGSizeMake(self.view.frame.width, self.view.frame.height)

    defaultSettings()
}

func defaultSettings() {
    self.firstNameTextField.delegate = self
    self.lastNameTextField.delegate = self
    self.emailTextField.delegate = self
    self.phoneNumberTextField.delegate = self
}

func deregisterFromKeyboardNotifications()
{
    //Removing notifies on keyboard appearing
    NSNotificationCenter.defaultCenter().removeObserver(self, name: UIKeyboardWillShowNotification, object: nil)
    NSNotificationCenter.defaultCenter().removeObserver(self, name: UIKeyboardWillHideNotification, object: nil)
}

func keyboardWasShown(notification: NSNotification)
{
    //Need to calculate keyboard exact size due to Apple suggestions
    //self.scrollView!.scrollEnabled = true
    var info : NSDictionary = notification.userInfo!
    var keyboardSize = (info[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.CGRectValue().size
    var contentInsets : UIEdgeInsets = UIEdgeInsetsMake(0.0, 0.0, keyboardSize!.height, 0.0)

    self.scrollView!.contentInset = contentInsets
    self.scrollView!.scrollIndicatorInsets = contentInsets

    var aRect : CGRect = self.view.frame
    aRect.size.height -= keyboardSize!.height
    if (!CGRectContainsPoint(aRect, activeTextField!.frame.origin))
    {
//            print(activeTextField?.frame)
//            var scrollPoint = CGPointMake(0.0, activeTextField!.frame.origin.y - (keyboardSize!.height-15))
        self.scrollView!.scrollRectToVisible((activeTextField?.frame)!, animated: true)
        //self.scrollView?.setContentOffset(scrollPoint, animated: true)
    }
}


func keyboardWillBeHidden(notification: NSNotification)
{
    //Once keyboard disappears, restore original positions
    //var info : NSDictionary = notification.userInfo!
    //var keyboardSize = (info[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.CGRectValue().size
    var contentInsets : UIEdgeInsets = UIEdgeInsetsZero
    self.scrollView!.contentInset = contentInsets
    self.scrollView!.scrollIndicatorInsets = contentInsets
//        self.view.endEditing(true)
//        self.scrollView!.scrollEnabled = false

}

func textFieldDidBeginEditing(textField: UITextField)
{
    activeTextField = textField
}

func textFieldDidEndEditing(textField: UITextField)
{
    activeTextField = nil
}

As you can see, I've tried scrollRectToVisible with frame and setContentOffset with Point. Both didn't work. Whereas the code picks on the emailTextField right as the hidden textfield.

Community
  • 1
  • 1
Viginesh
  • 258
  • 1
  • 3
  • 16
  • 1
    Use TPKeyboardAvoiding https://github.com/michaeltyson/TPKeyboardAvoiding. Its super easy, no it will take care of all. – Bharat Modi Jun 29 '16 at 12:21
  • 1
    @BharatModi, Thank you for your comment. I didn't want to use 3rd party API, looking to use Apple recommended method. – Viginesh Jun 29 '16 at 23:08

3 Answers3

22

I was also struggling with the same issue as you did, I don't know if you were successful and found solution, but I finally used setContentOffset function instead of scrollRectToVisible and it worked.

Swift 3.x example:

if (!aRect.contains(activeTextView!.frame.origin)) {
                self.scrollView.setContentOffset(CGPoint(x:0, y:self.activeTextView!.frame.origin.y), animated: true)
}
ivo
  • 262
  • 3
  • 8
  • ScrollRectToVisible was working fine for a while, I'm not sure what I did to cause it to stop, but this approach solved my problem. Thanks! – StoriKnow Apr 25 '19 at 11:41
2

SWIFT 4 Try this

scrollView.scrollRectToVisible(myElementView.frame, animated: true)

where myElementView can be any element

Álvaro Agüero
  • 4,494
  • 1
  • 42
  • 39
-3

You should also set the scrollView delegate as:

self.scrollView.delegate = self as! UIScrollViewDelegate

ScrollView delegate methods work with this.