提问人:Aditya Vyavahare 提问时间:11/2/2023 更新时间:11/3/2023 访问量:78
如何在UICollectionView上实现自定义分页,使其看起来像AppStore中的分页?
How to implement custom paging on UICollectionView to make it appear like the one in the AppStore?
问:
我想在UICollectionView中实现分页,使其看起来像AppStore
上一个单元格和下一个单元格应从前缘和后缘部分可见。我想给它一种感觉就像我们在 AppStore 的“应用程序”部分看到的那样。
下面是集合视图的配置代码。 我尝试实现insetForSectionAt函数,但这完全搞砸了集合视图的滚动行为。 任何帮助将不胜感激。谢谢!
//MARK: Configure collectionView
extension ViewController: UICollectionViewDelegate, UICollectionViewDataSource {
func setupCollectionView() {
imagesColletionView.delegate = self
imagesColletionView.dataSource = self
imagesColletionView.register(CustomCollectionViewCell.self, forCellWithReuseIdentifier: CustomCollectionViewCell.cellIdentifier)
view.addSubview(imagesColletionView)
// Set up horizontal scrolling and paging
if let layout = imagesColletionView.collectionViewLayout as? UICollectionViewFlowLayout {
layout.scrollDirection = .horizontal
layout.minimumLineSpacing = 0
imagesColletionView.isPagingEnabled = true
imagesColletionView.setCollectionViewLayout(layout, animated: false)
}
//Set constraints
imagesColletionView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
imagesColletionView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
imagesColletionView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor, constant: 10),
imagesColletionView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor, constant: -10),
imagesColletionView.heightAnchor.constraint(equalToConstant: UIScreen.main.bounds.height/4)
])
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return colors.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: CustomCollectionViewCell.cellIdentifier, for: indexPath) as! CustomCollectionViewCell
cell.backgroundColor = colors[indexPath.row]
return cell
}
// UIScrollViewDelegate method to detect scrolling
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
// Calculate the visible index based on content offset
let visibleRect = CGRect(origin: imagesColletionView.contentOffset, size: imagesColletionView.bounds.size)
let visiblePoint = CGPoint(x: visibleRect.midX, y: visibleRect.midY)
if let indexPath = imagesColletionView.indexPathForItem(at: visiblePoint) {
// Scroll to the corresponding row in the table view
let selectedRowIndexPath = IndexPath(row: indexPath.item, section: 0)
namesTableView.selectRow(at: selectedRowIndexPath, animated: true, scrollPosition: .top)
}
}
func scrollToCollectionViewItem(at indexPath: IndexPath) {
// Determine the corresponding index path in the collection view
let collectionViewIndexPath = IndexPath(item: indexPath.row, section: 0)
// Scroll to the item in the collection view
imagesColletionView.scrollToItem(at: collectionViewIndexPath, at: .centeredHorizontally, animated: true)
}
}
//enables horizontal scroll
extension ViewController: UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView,
layout collectionViewLayout: UICollectionViewLayout,
sizeForItemAt indexPath: IndexPath) -> CGSize {
let cellWidth = collectionView.bounds.width
let cellHeight = collectionView.bounds.height
return CGSize(width: cellWidth, height: cellHeight)
}
}
答:
0赞
Aditya Vyavahare
11/3/2023
#1
解决方案如下:
var imagesColletionView: UICollectionView!
extension ViewController: UICollectionViewDelegate, UICollectionViewDataSource {
func setupCollectionView() {
imagesColletionView = UICollectionView(frame: view.bounds, collectionViewLayout: createCompositionalLayout())
imagesColletionView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
imagesColletionView.backgroundColor = .systemBackground
imagesColletionView.delegate = self
imagesColletionView.dataSource = self
imagesColletionView.register(CustomCollectionViewCell.self, forCellWithReuseIdentifier: CustomCollectionViewCell.cellIdentifier)
view.addSubview(imagesColletionView)
imagesColletionView.isScrollEnabled = false //disable vertical scroll
//Set constraints
imagesColletionView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
imagesColletionView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
imagesColletionView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor),
imagesColletionView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor),
imagesColletionView.heightAnchor.constraint(equalToConstant: UIScreen.main.bounds.height/3)
])
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return images.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: CustomCollectionViewCell.cellIdentifier, for: indexPath) as! CustomCollectionViewCell
cell.cellImageView.image = UIImage(named: images[indexPath.row])
return cell
}
//used in taking data from tableview to go to respective cell
func scrollToCollectionViewItem(at indexPath: IndexPath) {
// Determine the corresponding index path in the collection view
let collectionViewIndexPath = IndexPath(item: indexPath.row, section: 0)
// Scroll to the item in the collection view
imagesColletionView.scrollToItem(at: collectionViewIndexPath, at: .centeredHorizontally, animated: true)
}
//use in custom paging
func createCompositionalLayout() -> UICollectionViewLayout {
let layout = UICollectionViewCompositionalLayout {
sectionIndex, layoutEnvironment in
let section = self.images[sectionIndex]
return self.createFeaturedSection()
}
return layout
}
func createFeaturedSection() -> NSCollectionLayoutSection {
let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1), heightDimension: .fractionalHeight(1))
let layOutItem = NSCollectionLayoutItem(layoutSize: itemSize)
layOutItem.contentInsets = NSDirectionalEdgeInsets(top: 0, leading: 5, bottom: 0, trailing: 5)
//this fractional width value decides the leading & trailing partial showing of cells.
let layoutGroupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(0.9), heightDimension: .estimated(350))
let layOutGroup = NSCollectionLayoutGroup.horizontal(layoutSize: layoutGroupSize, subitems: [layOutItem])
let layOutSection = NSCollectionLayoutSection(group: layOutGroup)
layOutSection.orthogonalScrollingBehavior = .groupPagingCentered
return layOutSection
}
}
但是,在实现 UICollectionViewCompositionalLayout 时,在水平方向上 UIScrollView 委托方法停止工作,因为将 orthogonalScrollingBehavior 设置为嵌入内部 UICollectionViewOrthogonalScrollerEmbeddedScrollView 的节 这个新的嵌入式滚动视图处理节中的滚动行为 因此,最终它将另一个内部子视图设置为集合视图(滚动行为处理程序),这是一个完全不同的实例 因此,我们无法对 UICollectionViewDelegate/UIScrollView 的委托方法进行任何回调
如果您知道任何允许将分页行为提供给集合视图,同时允许实现 UIScrollView 委托方法的解决方案,请随时发布另一个答案......
评论