Swift:如何在设备旋转后刷新UICollectionView布局
我使用UICollectionView(flowlayout)来构建简单的布局。 每个单元格的宽度设置为使用的屏幕宽度self.view.frame.width
Swift:如何在设备旋转后刷新UICollectionView布局
但是当我旋转设备时,单元格不会更新。
我找到了一个功能,它是在方向变化称为:
override func willRotateToInterfaceOrientation(toInterfaceOrientation:
UIInterfaceOrientation, duration: NSTimeInterval) {
//code
}
,但我无法找到一个方法来更新UICollectionView布局
主要代码这里:
class ViewController: UIViewController , UICollectionViewDelegate , UICollectionViewDataSource , UICollectionViewDelegateFlowLayout{
@IBOutlet weak var myCollection: UICollectionView!
var numOfItemsInSecOne: Int!
override func viewDidLoad() {
super.viewDidLoad()
numOfItemsInSecOne = 8
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func willRotateToInterfaceOrientation(toInterfaceOrientation: UIInterfaceOrientation, duration: NSTimeInterval) {
//print("orientation Changed")
}
func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
return 1
}
func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return numOfItemsInSecOne
}
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier("cellO", forIndexPath: indexPath)
return cell
}
func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize{
let itemSize = CGSize(width: self.view.frame.width, height: 100)
return itemSize
}}
添加此函数:
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
myCollection.collectionViewLayout.invalidateLayout()
}
当您更改方向时,将调用此函数。
您可以通过使用
func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize {
if isLandscape {
return CGSizeMake(yourLandscapeWidth, yourLandscapeHeight)
}
else {
return CGSizeMake(yourNonLandscapeWidth, yourNonLandscapeHeight)
}
}
更好的选择更新UICollectionView布局是调用invalidateLayout()
而不是reloadData()
因为它不会迫使细胞的娱乐,所以性能会稍好一些:
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
myCollection.collectionViewLayout.invalidateLayout()
}
这是正确的方法。这应该是被接受的答案。 – thesummersign
这是正确的方法来做到这一点..不是再次加载数据 –
,导致我暗恋。当我在viewDidLayoutSubviews函数中放置一个打印语句时,识别出一个无限循环。 – nyxee
你也可以通过这种方式使它无效。
- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator {
[super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
[self.collectionView.collectionViewLayout invalidateLayout];
}
更新UICollectionViewLayout
traitCollectionDidChange
方法可能被使用:
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
super.traitCollectionDidChange(previousTraitCollection)
guard let previousTraitCollection = previousTraitCollections else {
return
}
collectionView?.collectionViewLayout.invalidateLayout()
}
的viewWillLayoutSubviews()对我没有工作。 viewDidLayoutSubviews()也没有。两者都使应用程序进入无限循环,我使用打印命令进行了检查。
一个是做工作的方法之一是
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
// Reload here
}
感谢@ khuong291如果我没有我的CollectionView的对象,我有UICollectionViewController?我将如何调用reloadData? –
UICollectionViewController已经具有'collectionView'属性,所以你只要按照我所说的调用它们。只需将它们编辑为'collectionView.reloadData()'。它会工作。 – Khuong
所以你需要重新加载视图,你不能只是触发布局刷新? – Rivera