【发布时间】:2021-09-04 19:06:02
【问题描述】:
我正在尝试在水平胶片布局和垂直堆栈布局之间转换我的收藏视图。
这是我目前正在做的事情:
- 使用
setCollectionViewLayout(_:animated:completion:)在水平和垂直滚动方向之间转换 - 更改集合视图的高度约束,以及
UIView.animate和self.view.layoutIfNeeded()
从胶片到垂直堆栈的动画很好。但是,从垂直堆栈到胶片的动画被破坏了。这是它的样子:
如果我默认设置collectionViewHeightConstraint 300,并删除这些行:
collectionViewHeightConstraint.constant = 300
collectionViewHeightConstraint.constant = 50
...过渡动画两种方式都很好。但是,有多余的间距,我希望胶片布局仅在 1 行中。
我怎样才能让动画双向流畅?这是我的代码 (link to the demo project):
class ViewController: UIViewController {
var isExpanded = false
var verticalFlowLayout = UICollectionViewFlowLayout()
var horizontalFlowLayout = UICollectionViewFlowLayout()
@IBOutlet weak var collectionView: UICollectionView!
@IBOutlet weak var collectionViewHeightConstraint: NSLayoutConstraint!
@IBAction func toggleExpandPressed(_ sender: Any) {
isExpanded.toggle()
if isExpanded {
collectionView.setCollectionViewLayout(verticalFlowLayout, animated: true) /// set vertical scroll
collectionViewHeightConstraint.constant = 300 /// make collection view height taller
} else {
collectionView.setCollectionViewLayout(horizontalFlowLayout, animated: true) /// set horizontal scroll
collectionViewHeightConstraint.constant = 50 /// make collection view height shorter
}
/// animate the collection view's height
UIView.animate(withDuration: 1) {
self.view.layoutIfNeeded()
}
/// Bonus points:
/// This makes the animation way more worse, but I would like to be able to scroll to a specific IndexPath during the transition.
// collectionView.scrollToItem(at: IndexPath(item: 9, section: 0), at: .bottom, animated: true)
}
override func viewDidLoad() {
super.viewDidLoad()
verticalFlowLayout.scrollDirection = .vertical
horizontalFlowLayout.scrollDirection = .horizontal
collectionView.collectionViewLayout = horizontalFlowLayout
collectionView.dataSource = self
collectionView.delegate = self
}
}
extension ViewController: UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
/// if expanded, cells should be full-width
/// if not expanded, cells should have a width of 50
return isExpanded ? CGSize(width: collectionView.frame.width, height: 50) : CGSize(width: 100, height: 50)
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
return 0 /// no spacing needed for now
}
}
/// sample data source
extension ViewController: UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 10
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "ID", for: indexPath)
cell.contentView.layer.borderWidth = 5
cell.contentView.layer.borderColor = UIColor.red.cgColor
return cell
}
}
【问题讨论】:
-
更新:我一直在关注this article,我想我已经接近了。
-
似乎链接现在指向一篇新文章...无论如何,这里是accompanying github repo。
标签: ios swift uicollectionview