Reputation: 133
I am trying to add a constraint programmatically to selected UITextField inside UITableViewCell. It is added successfully and selected text field width is being increased. But when I try to remove the added constraint then it doesn't work. Can Any one figure out where Am I doing the mistake?
-(void)setViewMovedUp:(BOOL)movedUp
{
if (self.currentTextField.tag!=HEADER_FIELD_TAG) {
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.3]; // if you want to slide up the view
[self.view bringSubviewToFront:self.currentTextField];
NSLayoutConstraint *constraintTrail = [NSLayoutConstraint constraintWithItem:self.currentTextField.superview
attribute:NSLayoutAttributeTrailing
relatedBy:NSLayoutRelationEqual
toItem:self.currentTextField
attribute:NSLayoutAttributeTrailing
multiplier:1.0
constant:0.0];
CGRect rect = self.view.frame;
CGRect tableRect = self.currentTextField.frame;
if (movedUp)
{
// 1. move the view's origin up so that the text field that will be hidden come above the keyboard
// 2. increase the size of the view so that the area behind the keyboard is covered up.
[self.currentTextField.superview addConstraint:constraintTrail];
rect.origin.y -= kOFFSET_FOR_KEYBOARD;
rect.size.height += kOFFSET_FOR_KEYBOARD;
tableRect.size.width += 800;
}
else
{
// revert back to the normal state.
[self.currentTextField.superview removeConstraints:@[constraintTrail]];
rect.origin.y += kOFFSET_FOR_KEYBOARD;
rect.size.height -= kOFFSET_FOR_KEYBOARD;
tableRect.size.width -= 800;
}
infoFieldTable.frame = tableRect;
self.view.frame = rect;
[UIView commitAnimations];
}
}
Upvotes: 0
Views: 493
Reputation: 3494
My suggestion would be to add the constraint only once (maybe in the setup method or event the storyboard
and have an IBOutlet
to it) and then active/deactivate it according to your logic.
-(void)setViewMovedUp:(BOOL)movedUp
{
if (self.currentTextField.tag!=HEADER_FIELD_TAG) {
// All your logic here ...
// Set the active property on the constraint
[self.constraintTrail setActive:movedUp];
}
}
Another point would be that you are not calling layoutIfNeeded
after you change the constraints. This method causes the view to relayout it's subviews with the new constraints.
Hope it works! Let me know how it goes though :)
Upvotes: 0
Reputation: 6557
Well it's obviously not working.
If I imagine right, setViewMovedUp
is a setter, executed when the viewMovedUp
property changes.
When the method is executed, you create a new constraint with:
NSLayoutConstraint *constraintTrail = [NSLayoutConstraint constraintWithItem:self.currentTextField.superview
attribute:NSLayoutAttributeTrailing
relatedBy:NSLayoutRelationEqual
toItem:self.currentTextField
attribute:NSLayoutAttributeTrailing
multiplier:1.0
constant:0.0];
Based on the value of movedUp
you either add it or try to remove it. So if you set viewMovedUp
to YES
5 times in a row, you'll have 5 constraints. When you set it to NO
, you're trying to remove a newly created constraint, not the one which was previously added.
What you most likely want is to create a property for that constraint:
@property (nonatonic, strong) NSLayoutContraint *constraintTrail;
and change your code to:
if (!self.contraintTrail) {
self.contraintTail = [NSLayoutConstraint constraintWithItem:self.currentTextField.superview
attribute:NSLayoutAttributeTrailing
relatedBy:NSLayoutRelationEqual
toItem:self.currentTextField
attribute:NSLayoutAttributeTrailing
multiplier:1.0
constant:0.0];
}
This way, you only create on NSLayoutContraint
instance, and reuse it.
Upvotes: 1