Why a frame of a UIView is not updating in ViewDidLayoutSubviews?

nabrugir picture nabrugir · Mar 18, 2014 · Viewed 27.1k times · Source

I am trying to update the frame of a UIView which contains buttons and labels inside. I am trying to update it in viewDidLayoutSubviews (and I also tried in viewDidLoad, viewWillAppear, viewDidAppear..). I want to change the y position (origin.y) of the view. The NSLogs says my original y position is 334, and after changing, it is 100. However, the position does not change in my view. I have already checked that the view is connected in the storyboard. What am I doing wrong?

-(void)viewDidLayoutSubviews
{
    [super viewDidLayoutSubviews];
    CGRect theFrame  = [self.bottomView frame];
    NSLog(@"Y position bottomview: %f", self.bottomView.frame.origin.y);

    if([[UIScreen mainScreen] bounds].size.height == 568) //iPhone 4inch
    {
       // NSLog(@"iphone5");
    }
    else{
       // NSLog(@"iphone4");
        theFrame .origin.y =  100;
    }

    self.bottomView.frame = theFrame;
    NSLog(@"Y position bottomview after changing it: %f", self.bottomView.frame.origin.y);
    [self.view layoutIfNeeded];
}

Answer

Lars Blumberg picture Lars Blumberg · Dec 27, 2015

I've had the same problem. Forcing the layouting for your view's superview helped me out:

-(void)viewDidLayoutSubviews
{
    [super viewDidLayoutSubviews];
    [self.bottomView.superview setNeedsLayout];
    [self.bottomView.superview layoutIfNeeded];

    // Now modify bottomView's frame here
}

In Swift:

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()

    bottomView.superview!.setNeedsLayout()
    bottomView.superview!.layoutIfNeeded()

    // Now modify bottomView's frame here
}