swift 如何在UICollectionView上实现自定义分页,使其看起来像AppStore中的分页?

mkh04yzy  于 2023-11-16  发布在  Swift
关注(0)|答案(1)|浏览(168)

我想在UICollectionView中实现分页到make it appear like the 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)
    }
}

字符串

f4t66c6m

f4t66c6m1#

解决方案如下:

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委托方法的同时,允许给集合视图提供分页行为,请随意发布另一个答案。
Resource of solution

相关问题