Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Animating constraints causing subviews layout to be visible on screen

I have a messaging screen I am creating and I am almost done it. I built most of the views with nib files and constraints. I have one small bug however where I can visually see some of the cells laying themselves out when the keyboard dismisses because of the requirement to call [self.view layoutIfNeeded] in an animation block involving a constraint. Here is the problem:

- (void)keyboardWillHide:(NSNotification *)notification
{
    NSNumber *duration = [[notification userInfo] objectForKey:UIKeyboardAnimationDurationUserInfoKey];
    NSNumber *curve = [[notification userInfo] objectForKey:UIKeyboardAnimationCurveUserInfoKey];

    [UIView animateWithDuration:duration.doubleValue delay:0 options:curve.integerValue animations:^{
        _chatInputViewBottomSpaceConstraint.constant = 0;
        // adding this line causes the bug but is required for the animation.
        [self.view layoutIfNeeded]; 
    } completion:0];
}

Is there any way around directly calling layout if needed on the view since this also causes my collection view to lay itself out which makes the cells layout visually on screen sometimes.

I tried everything I can think of but it I can't find a solution to the bug fix. I have already tried calling [cell setNeedLayout]; in every location possible, nothing happens.

like image 351
DBoyer Avatar asked Oct 01 '14 15:10

DBoyer


1 Answers

How about this?

In your UITableViewCell implement a custom protocol called MYTableViewCellLayoutDelegate

@protocol MYTableViewCellLayoutDelegate <NSObject>
@required
- (BOOL)shouldLayoutTableViewCell:(MYTableViewCell *)cell;

@end

Create a delegate for this protocol @property (nonatomic, weak) id layoutDelegate;

Then override layoutSubviews on your UITableViewCell:

- (void)layoutSubviews {
    if([self.layoutDelegate shouldLayoutTableViewCell:self]) {
        [super layoutSubviews];
    }
}

Now, in your UIViewController you can implement the shouldLayoutTableViewCell: callback to control whether the UITableViewCell gets laid out or not.

-(void)shouldLayoutTableViewCell:(UITableViewCell *)cell {
    return self.shouldLayoutCells;
}

Modify your keyboardWillHide method to disable cell layout, call layoutIfNeeded, and restore the cell layout ability in the completion block.

- (void)keyboardWillHide:(NSNotification *)notification {
    NSNumber *duration = [[notification userInfo] objectForKey:UIKeyboardAnimationDurationUserInfoKey];
    NSNumber *curve = [[notification userInfo] objectForKey:UIKeyboardAnimationCurveUserInfoKey];

    self.shouldLayoutCells = NO;
    [UIView animateWithDuration:duration.doubleValue delay:0 options:curve.integerValue animations:^{
        _chatInputViewBottomSpaceConstraint.constant = 0;
        [self.view layoutIfNeeded]; 
    } completion:completion:^(BOOL finished) {
        self.shouldLayoutCells = NO;
    }];
}

I can't really test this since you didn't provide sample code, but hopefully this will put you on the right path.

like image 133
dfmuir Avatar answered Nov 20 '22 21:11

dfmuir