Reputation: 2283
Using autolayout I want to understand why the following happens: Creating a simple UIButton and setting its title. However, even though I expect the intrinsic content size of the view to be set and hence get its frame properly - the frame of the button is showing (0, 0, 0, 0). What do I have to do to get the frame value of the button ?
-(void)viewDidLoad {
[super viewDidLoad];
UIButton *button = [[UIButton alloc] init];
[button.titleLabel setText:@"My button"];
//button frame is zero
}
Yet if I am to do that, then things work as expected:
-(void)viewDidLoad {
[super viewDidLoad];
UILabel *label = [[UILabel alloc] init];
[label setText:@"My label"];
[label sizeToFit];
//label frame has the expected width and height
}
Upvotes: 1
Views: 2203
Reputation: 11
Just like @Andrea said: because you haven't added the button in IB, it is defaulting to using the autoResizingMask, which will keep the zero sized frame that the button initialised with.
If you want autolayout to work, you need to set
button.translatesAutoresizingMaskIntoConstraints = NO;
right before calling -addSubview:
.
In addition, you'll have to add at least 1 horizontal constraint and 1 vertical constraint, to position the button. Even after you do that, the button's frame will only be set after the next layout pass, which you can manually initiate by calling -layoutIfNeeded
.
Upvotes: 1
Reputation: 1048
- (void)viewDidLoad {
[super viewDidLoad];
UIButton *button = [UIButton buttonWithType:UIButtonTypeSystem];
button.translatesAutoresizingMaskIntoConstraints = NO;
[button setTitle:@"My button" forState:UIControlStateNormal];
[self.view addSubview:button];
}
- (void)viewDidLayoutSubviews {
//check frame of button
}
Upvotes: 1
Reputation: 26385
Autolayout sets views frame only after a layout pass, it's something that has cycle and is not called evertytime you add a view or modify constraints, that's why sometimes you need to call -setNeedsLayout
on a particular view.
The other point is that if you do not create constraints using interface builder or programmatically, autolayout automatically converts the view autoresizing masks into constraints (-translatesAutoresizingMaskIntoConstraints
property).
In this case if you set a text, you are forcing the view to express its intrinsic content size, that basically is the size of the label, if the intrinsic content size doesn't conflict to other constraints it wins, but you can only ask the button size after the layout pass. Try to check the button size inside .viewDidLayout
after the call of the same method to the super class
Upvotes: 4
Reputation: 9387
Add the button as a sub view and call layoutIfNeeded
on the subview. Access its frame after that.
Also make sure you add constraints for leading and top to position the button within its superview.
Upvotes: 0