这可能是 UIKit 中的一个错误。当 和 的同时发生变化时,就会发生size
这种contentOffset
情况UIScrollView
。测试这种行为是否也会在没有自动布局的情况下发生会很有趣。
我找到了解决此问题的两种解决方法。
使用 contentInset(消息方法)
正如在消息应用程序中可以看到的那样,UIScrollView
当显示键盘时,它的高度不会改变 - 消息在键盘下可见。你可以这样做。UICollectionView
删除和包含UITextField
and的视图之间的约束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 上的项目源代码。这个项目有点简化。我应该考虑在通知中传递的选项。messageComposeView
Bottom 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 风格。