这可能是 UIKit 中的一个错误。当 和 的同时发生变化时,就会发生size这种contentOffset情况UIScrollView。测试这种行为是否也会在没有自动布局的情况下发生会很有趣。
我找到了解决此问题的两种解决方法。
使用 contentInset(消息方法)
正如在消息应用程序中可以看到的那样,UIScrollView当显示键盘时,它的高度不会改变 - 消息在键盘下可见。你可以这样做。UICollectionView删除和包含UITextFieldand的视图之间的约束UIButton(我称之为messageComposeView)。UICollectionView然后在和之间添加约束Bottom Layout Guide。保持 和 之间的messageComposeView约束Bottom Layout Guide。然后使用contentInset将UICollectionView视觉上的最后一个元素保持在键盘上方。我是通过以下方式做到的:
- (void)updateKeyboardConstraint:(CGFloat)height animationDuration:(NSTimeInterval)duration {
self.bottomSpaceConstraint.constant = height;
[UIView animateWithDuration:duration delay:0 options:UIViewAnimationOptionBeginFromCurrentState animations:^{
CGPoint bottomOffset = CGPointMake(0, self.collectionView.contentSize.height - (self.collectionView.bounds.size.height - height));
[self.collectionView setContentOffset:bottomOffset animated:YES];
[self.collectionView setContentInset:UIEdgeInsetsMake(0, 0, height, 0)];
[self.view layoutIfNeeded];
} completion:nil];
}
这是和self.bottomSpaceConstraint之间的约束。这是显示其工作原理的视频。
更新 1:这是我在 GitHub 上的项目源代码。这个项目有点简化。我应该考虑在通知中传递的选项。messageComposeViewBottom Layout Guide - (void)keyboardWillShow:(NSNotification *)notif
在队列中执行更改
不是一个确切的解决方案,但如果将其移动到完成块,滚动效果很好:
} completion:^(BOOL finished) {
[self.collectionView setContentOffset:CGPointMake(0, self.collectionView.contentSize.height - self.collectionView.bounds.size.height) animated:YES];
}];
键盘显示需要 0.25 秒,因此动画开始之间的差异可能很明显。动画也可以以相反的顺序完成。
更新 2:我还注意到 OP 的代码适用于此更改:
CGPoint bottomOffset = CGPointMake(0, self.collectionView.contentSize.height - (self.collectionView.bounds.size.height - height));
但只有当contentSize'sheight小于某个固定值时(在我的情况下800,但我的布局可能有点不同)。
最后,我认为我提出的方法Using contentInset (the Messages approach)比调整大小更好UICollectionView。使用时,contentInset我们还可以看到键盘下的元素。它当然更适合 iOS 7 风格。