Reputation: 6532
I'm trying to programmatically add buttons to the horizontal center of a menu in iOS. SO that each button appears underneath the previous button.
My Menu is a UIView called viewToPlaceButtonsOn
and I've got a variable to store the last button placed called previousButton
.
Seems fairly simple right? Can anyone help me work out why I'm getting this so wrong?
- (void)makeButton:(NSString*) buttonTitle {
UIButton* menuButton = [[UIButton alloc] init];
[menuButton setTitle: buttonTitle forState:UIControlStateNormal];
[menuButton setBackgroundColor:[UIColor redColor]];
[viewToPlaceButtonsOn addSubview:menuButton];
[viewToPlaceButtonsOn addConstraint:[NSLayoutConstraint constraintWithItem:menuButton
attribute:NSLayoutAttributeCenterX
relatedBy:NSLayoutRelationEqual
toItem:previousButton
attribute:NSLayoutAttributeCenterX
multiplier:1.0f
constant:0.0f]];
[viewToPlaceButtonsOn addConstraint:[NSLayoutConstraint constraintWithItem:menuButton
attribute:NSLayoutAttributeTop
relatedBy:NSLayoutRelationEqual
toItem:previousButton
attribute:NSLayoutAttributeTop
multiplier:1.0f
constant:50.0f]];
[viewToPlaceButtonsOn addConstraint:[NSLayoutConstraint constraintWithItem:menuButton
attribute:NSLayoutAttributeWidth
relatedBy:NSLayoutRelationEqual
toItem:nil
attribute:NSLayoutAttributeNotAnAttribute
multiplier:1.0F
constant:200]];
[viewToPlaceButtonsOn addConstraint:[NSLayoutConstraint constraintWithItem:menuButton
attribute:NSLayoutAttributeHeight
relatedBy:NSLayoutRelationEqual
toItem:nil
attribute:NSLayoutAttributeNotAnAttribute
multiplier:1.0F
constant:40]];
NSLog(@"Button's Frame: %f x %f (%f x %f)", [menuButton frame].origin.x, [menuButton frame].origin.y, [menuButton frame].size.width, [menuButton frame].size.height);
previousButton = menuButton;
}
Upvotes: 0
Views: 394
Reputation: 4244
Try this, please tweak values as needed:
UIButton * menuButton = [UIButton new];
[menuButton setTitle: buttonTitle forState: UIControlStateNormal];
[menuButton setBackgroundColor: [UIColor redColor]];
[viewToPlaceButtonsOn addSubview: menuButton];
NSDictionary * views = NSDictionaryOfVariableBindings(viewToPlaceButtonsOn, menuButton, _previousButton);
NSNumber * menuButtonWidth = @(120.f);
NSNumber * menuButtonHeight = @(44.f);
NSNumber * verticalSpacing = @(10.f);
NSDictionary * metrics = NSDictionaryOfVariableBindings(menuButtonWidth, menuButtonHeight, verticalSpacing);
[viewToPlaceButtonsOn addConstraints: [NSLayoutConstraint constraintsWithVisualFormat: @"V:[viewToPlaceButtonsOn]-(<=1)-[menuButton]"
options: NSLayoutFormatAlignAllCenterX
metrics: metrics
views: views]];
[viewToPlaceButtonsOn addConstraints: [NSLayoutConstraint constraintsWithVisualFormat: @"V:[_previousButton]-(verticalSpacing)-[menuButton(==menuButtonHeight)]|"
options: 0
metrics: metrics
views: views]];
Upvotes: 0
Reputation: 2427
A couple things immediately pop out to me. You need to set
menuButton.translatesAutoresizingMaskIntoConstraints = NO;
In order for your constraints to be correct otherwise autolayout will add its own.
Also your NSLog will not be accurate because layout hasn't been run at that point. Once layoutSubviews has been called then your views frame will be set by autolayout. To confirm this you can use the debugger to print your button at the end of your method call
po menuButton
Then let it continue and then pause your program, copy and paste the memory address for your button that you get from the previous po statment and you should see that the frame was set
po 0x039484
Upvotes: 1