7

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.

DBoyer
  • 3,062
  • 4
  • 22
  • 32
  • What do you see when the cell lays itself out? Do you have a layoutSubviews override in your UITableViewCell? – dfmuir Oct 05 '14 at 03:03
  • My cells look like an exact copy of iMessage (chat bubbles), I can visually see the chat bubble growing in the cells that come back on screen after the keyboard dismisses. It does NOT happen on regular scrolling just when the view is layed out after keyboard dismisses.... No I do not having any code in layout subviews for the cell. – DBoyer Oct 05 '14 at 03:08
  • I think its actually animating the bubble growing...so strange. – DBoyer Oct 05 '14 at 03:14

1 Answers1

2

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.

dfmuir
  • 2,048
  • 1
  • 17
  • 14
  • Sadly no luck. :( Everything happens exactly the same way – DBoyer Oct 05 '14 at 04:02
  • 1
    I think I fixed it! I had the keyboard dismiss mode set to "on drag" which causes cells to fly on screen when keyboard dismisses..possible too quickly? Changing it to interactive seemed to make it go away. – DBoyer Oct 05 '14 at 04:09
  • You may as well post the full solution. I can see this being a problem for others. – dfmuir Oct 05 '14 at 04:21