David
David

Reputation: 447

UITextField position reset when entering text

I'm at a loss trying to understand a positioning problem with UITextFields on iOS. I've designed a simple user interface using Interface Builder, with a picture that takes up the top half of the screen, and then some text fields underneath where the user needs to enter some information. Everything is constrained using auto-layout and displays nicely. However, when the user starts editing a text field, either the keyboard moves up and hides the field, or the whole screen moves up and the picture gets hidden, none of which is acceptable, so my approach has been to move the text field to the top of the screen when the user starts editing it, and move it back to its former place when the editing is done. The moving up and down works fine. However, whenever I actually type any text in the field, it gets reset to its original position – actually, all views in the superview get reset to their original positions. I've tried removing constraints, or setting the vertical constraints to be removed at build time, nothing changes.

I've set up a very simple view controller that reproduces the problem: Simple view controller in Interface builder

The view controller class is totally basic as well:

import UIKit
class ViewController: UIViewController {
    @IBOutlet weak var textField: UITextField!
    @IBOutlet weak var textView: UITextView!
    override func viewDidLoad() {
        super.viewDidLoad()
    }
    override func viewDidAppear(_ animated: Bool) {
        textField.frame.origin.y = 100
        textView.frame.origin.y = 150
    }
}

Nothing fancy. When I launch it, I get the expected screen with the text areas moved into the blue zone:

original screen

If I type some text into the UITextView (the green one), nothing happens:

entering text in the UITextView

But as soon as I enter text into the UITextField (the red one), both text areas are moved back to their original position:

entering text in the UITextField

The same behaviour occurs on various iPhone simulators and on my own iPhone, so it's consistent.

I'm expecting that the whole view controller is getting some signal to redraw everything the way it was, but why? And why doesn't it happen when I enter text in the UITextView area? I'm probably going to be able to avoid the problem by using UITextViews instead of UITextFields, but I still don't know what's happening :-|

EDIT: I get it, I didn't realize that the constraints are something to play around with ;-). I ended up simply recreating the constraints with the proper ordering depending on what field is being brought to the top. All the answers helped though! Thanks a lot :-)

Upvotes: 1

Views: 2252

Answers (2)

Codetector
Codetector

Reputation: 774

So it did not happen because of the typing, it is caused by an "auto layout" recalculation.

To solve this, there are two solutions: 1. Edit the layout constraints so it match the desired layout (Either by code or changing the storyboard in the InterfaceBuilder.) 2. Implement a custom view render function and remove the auto layout constraints altogether.

I would recommend the first solution. As it is more "legit". Which I mean it conforms to the guideline of documentation. The second one is much more powerful, but at the same time easy to lose efficiency.

Upvotes: 3

Milan Nosáľ
Milan Nosáľ

Reputation: 19737

It's because you set the frames of both textfiels directly. Whenever the autolayout recalculates the frames, this directly set frames will lose effect. It does not matter when that happens - you should not do it that way. Just use autolayout completely - there are several questions on SO that address that issue, e.g.: How to make textFields stay in place when keyboard moves up? Swift

Or you can follow my answer to the exact same thing here - but move up only whatever you need (in your case you want to move up just the textFields). You don't event have to use the keyboard height, just react to keyboard changes to update the position constraints on the text fields.

Upvotes: 1

Related Questions