Prevent items in a view from being hidden by calling viewDidLayoutSubviews


I have been following a tutorial on how to implement a login with parse with the function of logging in with Facebook and Twitter, however, I find a detail.

In principle the elements of the main view are hidden by means of the viewDidLayoutSubviews function, that is, they are sent to the lower part of the screen and later they are moved upwards in the form of animation, this animation is executed in the viewDidAppear function.

Until then everything is perfect, however when I select some of the textFields that are part of the view to enter a text, as is obvious the keyboard appears and theoretically should move the elements upwards so as not to hide them when write, here I assume that the viewDidLayoutSubviews function is reactivated and executes the code fragment that hides all the elements in the lower part as it is done when the application is loaded to make the animation possible.

How can I prevent the elements from disappearing every time I try to type in any of the textFields ?

override func viewDidLoad() {

 // create an array of all the views we want to animate in when we launch the screen

        viewsToAnimate = [self.logInView?.usernameField, self.logInView?.passwordField, self.logInView?.logInButton, self.logInView?.passwordForgottenButton, self.logInView?.facebookButton, self.logInView?.signUpButton, self.logInView?.logo]

override func viewDidLayoutSubviews() {

        // We to position all the views off the bottom of the screen
        // and then make them rise back to where they should be
        // so we track their final position in an array
        // but change their frame so they are shifted downwards off the screen

        viewsFinalYPosition = [CGFloat]();
        for viewToAnimate in viewsToAnimate {
            let currentFrame = viewToAnimate.frame
            viewToAnimate.frame = CGRectMake(currentFrame.origin.x, self.view.frame.height + currentFrame.origin.y, currentFrame.width, currentFrame.height)

override func viewDidAppear(animated: Bool) {


        // Now we'll animate all our views back into view
        // and, using the final position we stored, we'll
        // reset them to where they should be
        if viewsFinalYPosition.count == self.viewsToAnimate.count {
            UIView.animateWithDuration(1, delay: 0.0, options: .CurveEaseInOut,  animations: { () -> Void in
                for viewToAnimate in self.viewsToAnimate {
                    let currentFrame = viewToAnimate.frame
                    viewToAnimate.frame = CGRectMake(currentFrame.origin.x, self.viewsFinalYPosition.removeAtIndex(0), currentFrame.width, currentFrame.height)
                }, completion: nil)



asked by Víctor Gonzal 27.12.2015 в 21:33

1 answer


Assign the starting position (hidden) in viewDidLoad or add a Boolean property:

var initialPositionSet = false

So in the viewDidLayoutSubviews you set it to true when the elements have already been hidden:

override func viewDidLayoutSubviews() {
    if !self.initialPositionSet {
        self.initialPositionSet = true

        // establecer posición inicial

I think something like this can work for you.

answered by 27.12.2015 / 21:54