1

I have multiple text fields on a view controller, and have implemented the textFieldShouldReturn function so that when I hit return, it goes to the next text field. However, right now the screen stays the same, so the active text field is covered up by the keyboard.

How can I make it so that the screen scrolls down and I can see the active text field?

Relevant code:

func textFieldShouldReturn(_ textField: UITextField) -> Bool {
        let nextTextFieldTag = textField.tag + 1
        let nextTextField = textField.superview?.viewWithTag(nextTextFieldTag)

        if nextTextField != nil {
            nextTextField?.becomeFirstResponder()
        } else {
            textField.resignFirstResponder()
        }

        return false
    }
user3628240
  • 877
  • 1
  • 23
  • 41
  • add your tried code always – Anbu.Karthik Apr 02 '18 at 04:37
  • your code is fine and correct , it goes to the next text field -- it works or not, your VC embed in scrollview or else – Anbu.Karthik Apr 02 '18 at 04:52
  • @Anbu.karthik yes, but I'm not sure how to make it so I can see the next textfield since the keyboard covers it up – user3628240 Apr 02 '18 at 04:52
  • your textfield is embed in scrollview or tableview or else (directly attached in VC) – Anbu.Karthik Apr 02 '18 at 04:54
  • @Anbu.karthik right now I have a custom view that's being set as the VC view. Is it possible to just add the custom view to a scrollView in the VC? – user3628240 Apr 02 '18 at 04:55
  • If you are using the tableview this might be helpful to you. UITextfield *t1 = // the textfield to which you are moving; CGPoint point = [t1 convertPoint:CGPointZero toView:TableV]; NSIndexPath *indP = [TableV indexPathForRowAtPoint:point]; – SRI Apr 02 '18 at 04:56
  • @user3628240 - i updated answer check once – Anbu.Karthik Apr 02 '18 at 05:03
  • use [IQKeyboardManager](https://github.com/hackiftekhar/IQKeyboardManager) Don't spend more time on such small issues... – Fahim Parkar Apr 02 '18 at 09:47

5 Answers5

0

The simplest way is using IQKeyboardManager (https://github.com/hackiftekhar/IQKeyboardManager)

All your need to do is add the IQKeyboardManager to your Pod, install it and add the initially code. That's all

Copy from https://github.com/hackiftekhar/IQKeyboardManager Add to your pod file

`pod 'IQKeyboardManagerSwift'`

In AppDelegate.swift, just import IQKeyboardManagerSwift framework and enable IQKeyboardManager.

import IQKeyboardManagerSwift

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?

    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {

      IQKeyboardManager.sharedManager().enable = true

      return true
    }
}

If you want to make it yourself.

  1. In your textFieldShouldReturn, get the frame of the active textfield
  2. New view.frame.y -= activeTextField.frame.y + space
  3. Change view.frame.y

Or you can add all your textfield to the scrollview and just simple change scrollview.contentOffset.y

PPL
  • 6,357
  • 1
  • 11
  • 30
Quoc Nguyen
  • 2,839
  • 6
  • 23
  • 28
0

There is two way to scroll in UIScrollView:

  • scrollView.setContentOffset(textField.frame.origin, animated: true).
  • scrollView.scrollRectToVisible(textField.frame, animated: true)
tphduy
  • 119
  • 7
0

I am assuming all your text fields on scroll view scrollView. Now you want next textfield nextTextField to scroll up. In that case -

In your if condition -

scrollView.contentOffset = CGPoint(x : 0, y : nextTextField.frame.y)
Blind Ninja
  • 1,063
  • 13
  • 28
0

Try this

In your viewDidLoad() like this

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

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

And use these functions to show UITextField from when keyboard is shown

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

@objc func keyboardWillHide(notification: NSNotification) {
    if let keyboardSize = (notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue{
        print(keyboardSize.height)
        if view.frame.origin.y < 0 {
            self.view.frame.origin.y += keyboardSize.height
        }
    }
}
Fahadsk
  • 1,099
  • 10
  • 24
0
  1. When you start to use an textfield and you want to move your ScrollView.

     weak var activeField:[UITextField]!       
     func textFieldDidBeginEditing(_ textField: UITextField) {
         activeField = textField 
         if let scroll = scrollVC
             {
                 scroll.keyboardDismissMode = 
                 UIScrollViewKeyboardDismissMode.interactive
                 scroll.setContentOffset(CGPoint.init(x: 0, y: 
                 self.activeField.frame.origin.y - 64), animated: true)
             }
            }
    
  2. When you dismiss your keyboard, use a return or use .becomeFirstResponder()

    func textFieldDidEndEditing(_ textField: UITextField) {
    if let scroll = scrollVC{
        scroll.setContentOffset(CGPoint.init(x: 0, y: activeField == 
        textField ? 0 : textField.frame.origin.y), animated: true)
    }
    
  3. An example how i use first responders when I have 2 or more TextFields: You should add all your UITextFields in Array.

      @objc func dismissKeyboard(){
        self.view.endEditing(true)
      }
    
      func textFieldShouldReturn(_ textField: UITextField) -> Bool {
        switch activeField {            
        case arrTextFields[0]:
            arrTextFields[1].becomeFirstResponder()
        case arrTextFields[1]:
            arrTextFields[2].becomeFirstResponder()
        default:
            dismissKeyboard()
        }
        return true
    }