[英]UICollectionViewCell resizing on device rotation
我在ViewController中嵌入了一个非常简单的UICollectionView。
UICollectionView使用自动布局(在IB中定义)来占用ViewController中的整个空间。
我的UICollectionViewCell具有相同的大小,它们占据了UICollectionView的整个空间,因为我只希望在ViewController中显示一个单元格。 UICollectionViewCell仅显示一个UIImage(嵌入在UIScrollView中以进行缩放)。
除非设备旋转,否则它工作正常。 出现错误消息:
未定义UICollectionViewFlowLayout的行为,因为:项目高度必须小于UICollectionView的高度减去该部分插入的上限值和下限值,减去内容插入的上限值和下限值。 相关的UICollectionViewFlowLayout实例为,并附加到; 动画= {bounds.origin =; bounds.size =; position =; }; 层=; contentOffset:{0,0}; contentSize:{4875,323}>集合视图布局:。
这很清楚,我需要调整UICollectionViewCell的大小以适合新的高度/宽度。 旋转后,UICollectionViewCell将显示适当的高度/宽度,但动画效果不佳。
这是代码:
@IBOutlet weak var theCollectionView: UICollectionView!
@IBOutlet weak var theFlowLayout: UICollectionViewFlowLayout!
override func viewDidLoad() {
super.viewDidLoad()
//theCollectionView.delegate = self
theCollectionView.dataSource = self
automaticallyAdjustsScrollViewInsets = false
theFlowLayout.itemSize = theCollectionView.frame.size
theFlowLayout.sectionInset = UIEdgeInsetsMake(0,0,0,0)
theFlowLayout.minimumLineSpacing = 0.0
theCollectionView.reloadData()
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
}
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransition(to: size, with: coordinator)
print("\(#function) \(view.frame.size)")
coordinator.animate(alongsideTransition: nil, completion: {
_ in
self.theFlowLayout.itemSize = self.theCollectionView.frame.size
})
}
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
print("\(#function) \(view.frame.size)")
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
print("\(#function) \(view.frame.size)")
}
问题是,如何以及何时执行UICollectionViewCell更改以避免警告并获得平滑的动画?
当设备旋转时,我可以看到以下内容:viewWillTransition(to:with :)(375.0,667.0)viewWillLayoutSubviews()(667.0,375.0)viewDidLayoutSubviews()(667.0,375.0)
该错误仅在viewDidLayoutSubviews()之后显示。 我试图在viewDidLayoutSubviews()中调用theFlowLayout.invalidateLayout(),但它不会改变问题。
我读过其他类似的问题,但找不到答案:-(
谢谢你的帮助,
塞巴斯蒂安
我还没有找到最好的解决方案,但至少可以奏效。
我使用viewWillTransition计算单元格的索引并在旋转后重置偏移量。 为避免动画效果不佳,我将Alpha设置为0,并在动画的开始处将其设置为1,然后在动画结束时将其设置为1。
viewWillLayoutSubviews用于使UICollectionViewFlowLayout和viewDidLayoutSubviews的布局无效以设置新的单元格大小。
也许会对其他人有所帮助,但是如果您有更好的解决方案,请与我们分享!
@IBOutlet weak var theCollectionView: UICollectionView! {
didSet {
theCollectionView.backgroundColor = UIColor.black
theCollectionView.delegate = self
theCollectionView.dataSource = self
}
}
@IBOutlet weak var theFlowLayout: UICollectionViewFlowLayout! {
didSet {
theFlowLayout.itemSize = theCollectionView.frame.size
theFlowLayout.sectionInset = UIEdgeInsetsMake(0,0,0,0)
theFlowLayout.minimumLineSpacing = 0.0
}
}
var assets:[PHAsset]!
var startAssetIndex = 0
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = UIColor.black
automaticallyAdjustsScrollViewInsets = false
theCollectionView.reloadData()
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
theCollectionView.scrollToItem(at: IndexPath(row:startAssetIndex, section:0), at: .left, animated: true)
}
/// Resize the collectionView during device rotation
///
/// - Parameters:
/// - size: New size of the viewController
/// - coordinator: coordinator for the animation
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransition(to: size, with: coordinator)
// Compute the index of the image/video currently displayed
let offset = self.theCollectionView.contentOffset;
let index = round(offset.x / self.theCollectionView.bounds.size.width);
// hide the collection view to avoid horrible animation during the rotation
// animation is horrible due to the offset change
theCollectionView.alpha = 0.0
coordinator.animate(alongsideTransition: nil, completion: {
_ in
// display the collectionView during the animation
self.theCollectionView.alpha = 1.0
// compute the new offset based on the index and the new size
let newOffset = CGPoint(x: index * self.theCollectionView.frame.size.width, y: offset.y)
self.theCollectionView.setContentOffset(newOffset, animated: false)
})
}
/// Invalidate the layout of the FlowLayout, it's mandatory for the rotation
override func viewWillLayoutSubviews() {
theFlowLayout.invalidateLayout()
super.viewWillLayoutSubviews()
}
/// Set the size of the items (mandatory for the rotation)
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
theFlowLayout.itemSize = theCollectionView.frame.size
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.