我正在尝试重新创建iOS Gallery App,其中用户有两个集合视图控制器,第一个显示所有可用的图像,第二个在用户点击图像(一个单元格)时显示。图像显示在另一个具有以下功能的集合视图控制器中:
DispatchQueue.main.async {
self.collectionView?.scrollToItem(at: self.customIndexPath, at: UICollectionView.ScrollPosition.centeredHorizontally, animated: false)
}
}
其中,当用户在上一个集合视图控制器中选择一个项目时,将设置自定义indexPath。
问题是,在第二个集合视图控制器中(单独显示图像的地方),我不知道如何制作,因此当用户向右或向左滑动时,下一个/上一个图像将显示并居中,就像在该图像上调用了上面的函数一样。
我试图在以下代码中调用上述函数
func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
let newIndexPath = IndexPath(item: indexPath.item, section: 0)
print("Item at \(indexPath.item)")
self.collectionView?.scrollToItem(at: newIndexPath, at: UICollectionView.ScrollPosition.centeredHorizontally, animated: true)
}
但是它的调用太早了,一旦用户开始向前或向后查看集合视图,该图像就会被下一张图像替换,我希望当用户滑动或至少移动时显示下一张图像并将其居中水平显示,上一张图片的一半以上没有显示,下一张图片的一半以上显示,用户松开并自动将下一张图片居中
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var collectionView: UICollectionView!
var customIndexPath = IndexPath()
let images:[UIImage] = [
UIImage(named: "image_1")!,
UIImage(named: "image_2")!,
UIImage(named: "image_3")!,
UIImage(named: "image_4")!,
UIImage(named: "image_5")!,
UIImage(named: "image_6")!,
UIImage(named: "image_7")!,
UIImage(named: "image_8")!,
]
override func viewDidLoad() {
super.viewDidLoad()
collectionView.delegate = self
// Do any additional setup after loading the view, typically from a nib.
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
print(customIndexPath)
DispatchQueue.main.async {
self.collectionView?.scrollToItem(at: self.customIndexPath, at: UICollectionView.ScrollPosition.centeredHorizontally, animated: false)
}
}
}
extension ViewController: UICollectionViewDataSource, UICollectionViewDelegate {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return images.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! CollectionViewCell
cell.userImageView.image = images[indexPath.item]
return cell
}
func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
let newIndexPath = IndexPath(item: indexPath.item, section: 0)
print("Item at \(indexPath.item)")
self.collectionView?.scrollToItem(at: newIndexPath, at: UICollectionView.ScrollPosition.centeredHorizontally, animated: true)
}
}
在非常基本的级别上,结果应与iOS Gallery App非常相似,当用户滑动时,必须显示下一张图像并居中,而不是像现在这样浮动或部分显示,也要用户滑动慢慢地,并且下一个单元格(下一个图像)的内容至少有一半没有显示,那么收藏视图必须显示并居中显示上一张图像,就像iOS Gallery App一样
到目前为止,我的项目可以在以下链接中找到:
https://github.com/francisc112/Gallery-Test
在此先感谢您,如果有任何我可以学习的教程,请指出。
答案 0 :(得分:0)
我只是尝试使用一些不同的方法来解决此问题。我只使用scrollViewWillEndDragging
和scrollViewDidEndDragging
方法。我还使用了previousCollectionViewContentOffsetX
属性,该属性用于告诉我们在拖动结束时是否应滚动到下一个或上一个单元格,以防用户快速滚动(这是PhotosApp的行为)。
最后,我只是设置了一个快速的减速率来模拟分页功能:
collectionView.decelerationRate = .fast
您可以看到此解决方案in the pull request i've just made in your repo。
另一个更简单的解决方案是将collectionView的单元格和行的最小间距设置为零,并启用collectionView的分页。我们失去了PhotosApp显示的照片之间的边距,但避免触摸滚动视图委托。如果您愿意,我可以使用此解决方案提出拉取请求。