juminoz
juminoz

Reputation: 3218

Resizing UITextView Without Losing Constraints

I'm trying to figure out how to resize UITextView (and everything actually) without losing constraints. Basically, I'm trying to layout a page where most components can have variable sizes (like description). I tried doing it with a simple use case where I have a UITextView and a UIButton underneath. I want to make sure that the position of the button is relative to the bottom of the UITextView.

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];
    CGRect frame = self.textView.frame;
    int height = self.textView.contentSize.height;
    frame.size.height = height;
    self.textView.frame = frame;
}

What I ended up with is UITextView overlapping with UIButton. After doing a bit of research, it seems that if I replace the frame, all constraints are gone also. I tried copying the constraints over, but of course the pointer is still pointing at the old frame so that didn't help at all.

Is there a good way to solve a very dynamically laid out page? I'm trying to at least use interface builder rather than code everything.

EDITED

I tried updating the constraint as suggested, but that didn't actually resize the UITextView. Did I do it incorrectly? When I get the constant again, it's updated, but the height isn't changed visually. I did simplify my code by adding an IBOutlet for the constraint. Still no luck however.

int height = self.textView.contentSize.height;
self.textViewHeightConstraint.constant = height;

EDITED 2

I figured it out now. I had an extra constraint for the bottom and that was stopping me from actually resizing the UITextView.

Upvotes: 1

Views: 2597

Answers (1)

Rob
Rob

Reputation: 437552

The issue is how you've defined your button's top constraint. If it's to the label, when you adjust the label's height constraint, the button will move. For example, if doing it programmatically:

UILabel *label = [[UILabel alloc] init];
label.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:label];
label.text = @"Hello world";

UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[button setTitle:@"Submit" forState:UIControlStateNormal];
button.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:button];

NSDictionary *views = NSDictionaryOfVariableBindings(label, button);
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-[label]" options:0 metrics:nil views:views]];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-[button]" options:0 metrics:nil views:views]];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-[label]-[button]" options:0 metrics:nil views:views]];
NSLayoutConstraint *heightConstraint = [NSLayoutConstraint constraintWithItem:label attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:20];
[label addConstraint:heightConstraint];

Then, if you change the label's height constraint, the button will move:

heightConstraint.constant = 100;
[UIView animateWithDuration:1.0 animations:^{
    [self.view layoutIfNeeded];
}];

If you've defined your UI in Interface Builder, select the button and check the top constraint of the button and make sure it's to the label, not the superview:

top constraint

But, again, if the button's top constraint is to the label, when the label's height constraint changes, the button will move.

Upvotes: 1

Related Questions