页面控件不适用于 UITableView 内的 UICollectionView

发布于 2025-01-15 16:58:15 字数 4467 浏览 5 评论 0原文

我在使页面控制适用于表视图内的集合视图时遇到问题。视图控制器中实际上有 2 个集合视图,一个位于 tableView 外部,另一个位于 tableView 内部。我想要内部的页面控制。让我分享下面的代码,然后解释一下造成问题的原因:

class HomeViewController: UIViewController, UITableViewDataSource, UITableViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {

     override func viewDidLoad() {
        super.viewDidLoad()

        //setup stories collection view
        let nib = UINib(nibName: "StoryCollectionViewCell", bundle: nil)
        cvStories.register(nib, forCellWithReuseIdentifier: "StoryCollectionViewCell")
        let layout1 = UICollectionViewFlowLayout()
        layout1.scrollDirection = .horizontal
        layout1.sectionInset = UIEdgeInsets(top: 5, left: 5, bottom: 5, right: 5)
        collectionViewStories.setCollectionViewLayout(layout1, animated: true)
        collectionViewStories.delegate = self
        collectionViewStories.dataSource = self
        
        tblHome.dataSource = self
        tblHome.delegate = self
     }


    // MARK: - Table View
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return posts.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        
        let cell = tblHome.dequeueReusableCell(withIdentifier: "HomeTableViewCell", for: indexPath) as! HomeTableViewCell
        
        cell.collectionViewPostImages.dataSource = self
        cell.collectionViewPostImages.delegate = self
        cell.collectionViewPostImages.tag = indexPath.row
        cell.collectionViewPostImages.reloadData()
        
        cell.pageControl.hidesForSinglePage = true
        cell.pageControl.numberOfPages = self.posts[cell.collectionViewPostImages.tag].imagesArray?.count ?? 0
        
        return cell
        
    }

    //MARK: - Collection View
    func numberOfSections(in collectionView: UICollectionView) -> Int {
        if collectionView == cvStories {
            return 2
        }
        else {
            return 1
        }
    }

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        if collectionView == collectionViewStories {
            return stories.count
        }
        else {
            return posts[collectionView.tag].imagesArray?.count ?? 0
        }
    }
    
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        
        if collectionView == collectionViewStories {
            
            let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "StoryCollectionViewCell", for: indexPath) as! StoryCollectionViewCell
            //code to show stories
            return cell
            
        }
        else {
            
            let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "HomeCollectionViewCell", for: indexPath) as! HomeCollectionViewCell
            //code to show images
            return cell
            
        }
        
    }

}

//TableViewCell Class
class HomeTableViewCell: UITableViewCell {
   
    @IBOutlet weak var collectionViewPostImages: UICollectionView!
    @IBOutlet weak var pageControl: UIPageControl!
    
    var currentPage = 0
    
    override func awakeFromNib() {
    
        let flowLayout = UICollectionViewFlowLayout()
        flowLayout.itemSize = CGSize(width: UIScreen.main.bounds.size.width, height: cvPostImages.frame.size.height)
        flowLayout.scrollDirection = .horizontal
        flowLayout.minimumInteritemSpacing = 0
        flowLayout.minimumLineSpacing = 0
        collectionViewPostImages?.collectionViewLayout = flowLayout

        collectionViewPostImages.showsHorizontalScrollIndicator = false
        
        collectionViewPostImages.isPagingEnabled = true
        
    }
    
    //ScrollView delegate method
    func scrollViewDidScroll(_ scrollView: UIScrollView) {
        let pageWidth = scrollView.frame.width
        self.currentPage = Int((scrollView.contentOffset.x + pageWidth / 2) / pageWidth)
        self.pageControl.currentPage = self.currentPage
    }
    
}

整个代码就像 Instagram 应用程序,顶部的故事和 tableView 中带有图像的帖子。整个代码位于单个视图控制器中,一切正常。根据页数,即使点(页码)也是正确的,但是当您在它们之间滑动时,它们不会改变。我看到了很多解决方案,其中 pageControl.numberOfPages 用于 cellForItemAt 函数,但它超出了我的范围,所以我只是在 cellForRowAt 中将其称为 cell.pageControl.numberOfPages 。第一次在 tableView 中处理 collectionView 所以很困惑如何让它工作。

Im having issue with making page control work for a collection view which is inside table view. There are actually 2 collection views in the view controller, one is outside the tableView and other one is inside. I want page control for inside one. Let me share code below and then explain what is causing trouble:

class HomeViewController: UIViewController, UITableViewDataSource, UITableViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {

     override func viewDidLoad() {
        super.viewDidLoad()

        //setup stories collection view
        let nib = UINib(nibName: "StoryCollectionViewCell", bundle: nil)
        cvStories.register(nib, forCellWithReuseIdentifier: "StoryCollectionViewCell")
        let layout1 = UICollectionViewFlowLayout()
        layout1.scrollDirection = .horizontal
        layout1.sectionInset = UIEdgeInsets(top: 5, left: 5, bottom: 5, right: 5)
        collectionViewStories.setCollectionViewLayout(layout1, animated: true)
        collectionViewStories.delegate = self
        collectionViewStories.dataSource = self
        
        tblHome.dataSource = self
        tblHome.delegate = self
     }


    // MARK: - Table View
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return posts.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        
        let cell = tblHome.dequeueReusableCell(withIdentifier: "HomeTableViewCell", for: indexPath) as! HomeTableViewCell
        
        cell.collectionViewPostImages.dataSource = self
        cell.collectionViewPostImages.delegate = self
        cell.collectionViewPostImages.tag = indexPath.row
        cell.collectionViewPostImages.reloadData()
        
        cell.pageControl.hidesForSinglePage = true
        cell.pageControl.numberOfPages = self.posts[cell.collectionViewPostImages.tag].imagesArray?.count ?? 0
        
        return cell
        
    }

    //MARK: - Collection View
    func numberOfSections(in collectionView: UICollectionView) -> Int {
        if collectionView == cvStories {
            return 2
        }
        else {
            return 1
        }
    }

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        if collectionView == collectionViewStories {
            return stories.count
        }
        else {
            return posts[collectionView.tag].imagesArray?.count ?? 0
        }
    }
    
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        
        if collectionView == collectionViewStories {
            
            let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "StoryCollectionViewCell", for: indexPath) as! StoryCollectionViewCell
            //code to show stories
            return cell
            
        }
        else {
            
            let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "HomeCollectionViewCell", for: indexPath) as! HomeCollectionViewCell
            //code to show images
            return cell
            
        }
        
    }

}

//TableViewCell Class
class HomeTableViewCell: UITableViewCell {
   
    @IBOutlet weak var collectionViewPostImages: UICollectionView!
    @IBOutlet weak var pageControl: UIPageControl!
    
    var currentPage = 0
    
    override func awakeFromNib() {
    
        let flowLayout = UICollectionViewFlowLayout()
        flowLayout.itemSize = CGSize(width: UIScreen.main.bounds.size.width, height: cvPostImages.frame.size.height)
        flowLayout.scrollDirection = .horizontal
        flowLayout.minimumInteritemSpacing = 0
        flowLayout.minimumLineSpacing = 0
        collectionViewPostImages?.collectionViewLayout = flowLayout

        collectionViewPostImages.showsHorizontalScrollIndicator = false
        
        collectionViewPostImages.isPagingEnabled = true
        
    }
    
    //ScrollView delegate method
    func scrollViewDidScroll(_ scrollView: UIScrollView) {
        let pageWidth = scrollView.frame.width
        self.currentPage = Int((scrollView.contentOffset.x + pageWidth / 2) / pageWidth)
        self.pageControl.currentPage = self.currentPage
    }
    
}

The whole code is like Instagram app, stories at top and posts with images in tableView. Whole code is in single View controller and everything works fine. Even dots (page number) are correct according to number of pages however when you swipe between them they do not change. I saw many solutions and in those pageControl.numberOfPages was used in cellForItemAt function but its out of scope for me so I just called it as cell.pageControl.numberOfPages in cellForRowAt instead. First time dealing with collectionView inside tableView so getting confused getting it worked.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

只有影子陪我不离不弃 2025-01-22 16:58:15

主要问题是您在 HomeViewController 中使用 cell.collectionViewPostImages.delegate = self 但在单元格 HomeTableViewCell 中使用 scrollViewDidScroll 方法。

Collectionview 自己的滚动视图委托方法在 UICollectionViewDelegate 中触发。这就是为什么 scrollViewDidScroll 在你的单元格中没有被触发。

解决方案是在删除 CollectionView 的地方使用 scrollViewDidScroll 。它是HomeViewController

顺便说一句,我不建议在可重用单元格中使用 cell.collectionViewPostImages.dataSource = self cell.collectionViewPostImages.delegate = self 。您不想每次重用单元格时都创建 ...delegate = self 。您可以在单元类中的awakeFromNib中获取它

The main problem is you use cell.collectionViewPostImages.delegate = self in HomeViewController but your method scrollViewDidScroll in cell HomeTableViewCell.

Collectionview's own scrollview delegate methods triggering in UICollectionViewDelegate. Thats why scrollViewDidScroll is not triggered in your cell.

Solution is using scrollViewDidScroll in where you delegete the collectionview. It is HomeViewController

By the way, I dont recommend to use cell.collectionViewPostImages.dataSource = self cell.collectionViewPostImages.delegate = self in reusable cell. You dont want to make ...delegate = self on everytime when cell reused. You can take it in awakeFromNib in cell class

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文