Updating a xib view's position after a uiviewc

2019-07-21 10:42发布

I have a simple UIViewController which has a corresponding .xib file.

ViewController *v = [[ViewController alloc] initWithNibName:@"ViewController" bundle:[NSBundle mainBundle]];
[self.navigationController pushViewController:v animated:YES];

In this .xib file, I have a UILabel, which is positioned in the middle of the screen. I would like to move this label to a new position once the view is loaded, but before it is visible:

label.center = CGPointMake(0,0);

When I try putting the above code in the following methods, this is what happens:

  • initWithNibName:bundle: position doesn't update
  • awakeFromNib: position doesn't update
  • viewDidLoad: position doesn't update
  • viewWillAppear: position doesn't update
  • viewDidAppear: position only updates after the view is fully loaded (i.e. the label's original position can be seen for a split second).

When I try updating something like the text property:

label.text = @"Foo";

... it works in all of these methods. For some reason, it is only the position that gets overridden by the .xib file.

When I say that "position doesn't update" I mean that when the label is shown on the screen, it is in the location defined in the .xib file rather than the one I am trying to override it with.

When I try to NSLog the position, it shows that it updates it correctly, but then when I check the position again in viewDidAppear, it shows the incorrect value. For example, say the .xib defines the x at 99, and I want to change it to 0:

- (void)viewWillAppear:(BOOL)animated {
    label.center = CGPointMake(0,0);
    NSLog(@"%f", label.center.x); // reports 0
}

- (void)viewDidAppear:(BOOL)animated {
    NSLog(@"%f", label.center.x); // reports 99 (Error: should be 0)
    label.center = resultLabelHiddenCenter;
    NSLog(@"%f", label.center.x); // reports 0
}

How can I update the label's center before the view is shown without any visual glitches?

1条回答
小情绪 Triste *
2楼-- · 2019-07-21 11:03

I think , You are using autoLayout for your xib.

enter image description here

I have two solutions for you in my mind.

First one is , please don't use setFrame or setBounds because Autolayout will skip them.

Changing the constraints is the best solution .You can also add/remove extra constraints.

A good video tutorial is available in WWDC 2012 regarding Autolayout adjustments.

enter image description here

Second one is,Implement viewDidLayoutSubviews which will call just after the view controller's view's layoutSubviews method is invoked.

- (void)viewDidLayoutSubviews
{
    @try
    {
         // reset label frame here.
    }
    @catch (NSException *exception)
    {
        NSLog(@"%s\n exception: Name- %@ Reason->%@", __PRETTY_FUNCTION__,[exception name],[exception reason]);
    }
}
查看更多
登录 后发表回答