动画约束导致子视图布局在屏幕上可见

DBo*_*yer 7 uiviewanimation ios autolayout uicollectionview nslayoutconstraint

我有一个我正在创建的消息传递屏幕,我差不多完成了它.我使用nib文件和约束构建了大多数视图.我有一个小bug,但是当键盘解散时,我可以直观地看到一些单元格出现,因为需要在涉及约束的动画块中调用[self.view layoutIfNeeded].这是问题所在:

- (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];
}
Run Code Online (Sandbox Code Playgroud)

如果需要在视图上直接调用布局是否有任何方法,因为这也会导致我的集合视图自行布局,这有时会使单元格在屏幕上可视化.

我尝试了所有我能想到的但是我无法找到错误修复的解决方案.我已经尝试过调用[cell setNeedLayout]; 在每个可能的位置,没有任何反应.

dfm*_*uir 2

这个怎么样?

在您的 UITableViewCell 中实现一个名为 MYTableViewCellLayoutDelegate 的自定义协议

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

@end
Run Code Online (Sandbox Code Playgroud)

为此协议创建一个委托@property(非原子,弱)idlayoutDelegate;

然后覆盖 UITableViewCell 上的layoutSubviews:

- (void)layoutSubviews {
    if([self.layoutDelegate shouldLayoutTableViewCell:self]) {
        [super layoutSubviews];
    }
}
Run Code Online (Sandbox Code Playgroud)

现在,在 UIViewController 中,您可以实现 shouldLayoutTableViewCell: 回调来控制 UITableViewCell 是否布局。

-(void)shouldLayoutTableViewCell:(UITableViewCell *)cell {
    return self.shouldLayoutCells;
}
Run Code Online (Sandbox Code Playgroud)

修改keyboardWillHide方法以禁用单元格布局,调用layoutIfNeeded,并在完成块中恢复单元格布局功能。

- (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;
    }];
}
Run Code Online (Sandbox Code Playgroud)

我无法真正测试这一点,因为您没有提供示例代码,但希望这能让您走上正确的道路。