I have put together a simple view controller programmatically with just two buttons on it. If I go old school and set frame sizes for the layout then everything is fine. However if I use auto layout constraints for the layout then the buttons appear perfectly, but they do not respond to presses. They don't even highlight. My loadview method is below in the form that leaves the buttons not working. If the frame setting code is uncommented and the constraints adding commented out, then the buttons start to respond to presses as expected. Does anyone have any idea what is going on? I would love to translate all old hardcoded layout in my code base to be constraints based, but seem to be falling at the first hurdle.
- (void)loadView {
self.view = [UIView new];
self.view.translatesAutoresizingMaskIntoConstraints = NO;
self.navigationItem.title = @"Landing Page";
UIButton *buildExercisesButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
self.buildExercisesButton = buildExercisesButton;
// buildExercisesButton.frame = CGRectMake(20, 312, 164, 44);
self.buildExercisesButton.translatesAutoresizingMaskIntoConstraints = NO;
[self.buildExercisesButton setTitle:@"Build Exercises" forState:UIControlStateNormal];
[self.buildExercisesButton addTarget:self action:@selector(buildExercisesButtonPressed) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:self.buildExercisesButton];
UIButton *organiseExercisesButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
self.organiseExercisesButton = organiseExercisesButton;
// organiseExercisesButton.frame = CGRectMake(192, 312, 164, 44);
self.organiseExercisesButton.translatesAutoresizingMaskIntoConstraints = NO;
[self.organiseExercisesButton setTitle:@"Organise Exercises" forState:UIControlStateNormal];
[self.organiseExercisesButton addTarget:self action:@selector(organiseExercisesButtonPressed) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:self.organiseExercisesButton];
NSDictionary *variables = NSDictionaryOfVariableBindings(buildExercisesButton, organiseExercisesButton);
NSArray *constraints =
[NSLayoutConstraint constraintsWithVisualFormat:@"|-[buildExercisesButton(organiseExercisesButton)]-[organiseExercisesButton]-|"
options:NSLayoutFormatAlignAllTop | NSLayoutFormatAlignAllBottom
metrics:nil
views:variables];
[self.view addConstraints:constraints];
constraints =
[NSLayoutConstraint constraintsWithVisualFormat:@"V:[buildExercisesButton]-|"
options:0
metrics:nil
views:variables];
[self.view addConstraints:constraints];
}
In viewDidAppear I print out the frames of the buttons. They are giving weird values, which I don't know if it is related or not. In reality the buttons are displayed beside each other in the center of the screen.
buildExercisesButton: {{20, -63}, {164, 44}}
organiseExercisesButton: {{192, -63}, {164, 44}}
You need to define constraints for the view that you are adding buttons or set the translatesAutoresizingMaskIntoConstraints
property to YES
.
If you're doing purely Storyboard for autolayout, try increasing Vertical Content Hugging Priority and Vertical Compression Resistance Priority:
It looks like the UIButton
frames are off the screen. The touch events depend on hitting those not the images of the buttons so that's why they're not responding.
Why are you using the auto layout instead of setting the frames?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With