user3181273
user3181273

Reputation:

Delete/modify autolyout constraint in code

Background: I'm building a forum using the interface builder, where there is a table view in the view controller and an input accessory view outside. At runtime the input accessory view will be added to the table view and become a messenger-like input bar.

enter image description here

I was trying to implement the auto resizing feature (commonly seen in messaging apps) on the input accessory view, by changing the height constraints. However, there is no way to create a height constraint of the input accessory view in the interface builder, so I just added them in code.

NSLayoutConstraint *inputAccessoryConstraint = [NSLayoutConstraint constraintWithItem:self.inputAccessoryView
                                                                            attribute:NSLayoutAttributeHeight
                                                                            relatedBy:NSLayoutRelationEqual
                                                                               toItem:nil attribute:NSLayoutAttributeNotAnAttribute
                                                                           multiplier:1.0
                                                                             constant:100];

[self.inputAccessoryView addConstraint:inputAccessoryConstraint];

And got the following warnings:

Unable to simultaneously satisfy constraints.
...
(
"<NSLayoutConstraint:0x7fa5a413f450 V:[UIView:0x7fa5a264f8d0(100)]>",
"<NSLayoutConstraint:0x7fa5a2483890 '_UIKBAutolayoutHeightConstraint' V:[UIView:0x7fa5a264f8d0(44)]>"
)

The problem is that my new constraint is conflicting with one of the autolayout constraints that are added in the runtime. How do I delete/modify that autolayout constraint in code?

Upvotes: 1

Views: 1237

Answers (3)

Emmanuel Paris
Emmanuel Paris

Reputation: 200

I had the same issue and found an easy workaround for it. Just embed your Send button and Text view into an intermediate view. Force the height of that view to 100.f and attach it to its super view (ie: the keyboard input accessory view) on the left, right and bottom using auto-layout constraints. Then make sure the input accessory view doesn't clip it's subviews.

And voila, the system will still resize the input accessory view height to 44.f, but it doesn't matter, visually it'll be the expected size. And no warnings.

enter image description here

Upvotes: 0

Tometoyou
Tometoyou

Reputation: 8376

Hey I found out the best way to solve this is as Mathieu said, by altering the constant of _UIKBAutolayoutHeightConstraint. This can be achieved like this in Objective-C:

NSLayoutConstraint *constraint = [[self.inputAccessoryView constraints] objectAtIndex:0];
constraint.constant = 100;

Or like this in Swift:

let constraint:NSLayoutConstraint = (inputAccessoryView!.constraints() as NSArray).objectAtIndex(0) as NSLayoutConstraint
constraint.constant = 52

If you want it to reload the height of the inputAccessoryView before the view appears, this can be performed in updateViewConstraints. Hope this helps.

Upvotes: 0

Mathieu
Mathieu

Reputation: 96

You may want to remove an existing Height Constraint (44) before adding yours (100). But you may also be able to just edit the existing constraint:

The block below is browsing the constraints of your inputAccessoryView and find the height Constraint. It then sets the value to 100 instead of 44.

for (NSLayoutConstraint* constraint in YOURINPUTACCESSORYVIEW.constraints) {
    if ([NSStringFromClass([NSLayoutConstraint class]) isEqualToString:NSStringFromClass([constraint class])])
    {
        if (constraint.firstAttribute == NSLayoutAttributeHeight || constraint.secondAttribute == NSLayoutAttributeHeight)
        {
            constraint.constant = 100;
        }
    }
}

Upvotes: 1

Related Questions