单击选项卡栏时如何将表格视图发送到集合视图单元格的顶部?

问题描述

所以我有一个带有集合视图的视图控制器,其中包含 numberOfItemsInSection 中的两个集合视图单元格。每个单元格中都有一个表格视图。当我的某个标签栏项目被点击时,我试图转到 tableview 的顶部。我的问题是我无法访问集合视图单元格中的标签栏,当我访问视图控制器中的标签栏并从视图控制器调用集合视图单元格中的函数时,它不起作用(它说我我的 tableview 中没有任何行)。

这是我在视图控制器中设置集合视图,并在视图控制器中调用 func tabBarController(_ tabBarController: UITabBarController,didSelect viewController: UIViewController) 时尝试将集合视图单元格的 tableview 发送到顶部。

class AllPostsVC: UIViewController,UICollectionViewDelegate,UICollectionViewDataSource,UICollectionViewDelegateFlowLayout,UITabBarControllerDelegate {
   var indexPath:IndexPath?

   override func viewDidLoad() {
        super.viewDidLoad()
        setupCollectionView()       
        self.tabBarController?.delegate = self
    }

    lazy var collectionView: UICollectionView = {
        let layout = UICollectionViewFlowLayout()
        layout.scrollDirection = .horizontal
        layout.minimumLinespacing = 0
        let cv = UICollectionView(frame: .zero,collectionViewLayout: layout)
        cv.dataSource = self
        cv.delegate = self
        return cv
    }()

    func setupCollectionView() {
        
        view.addSubview(collectionView)
        
        view.bringSubviewToFront(collectionView)
        
        collectionView.isPagingEnabled = true
        
        collectionView.translatesAutoresizingMaskIntoConstraints = false
        collectionView.heightAnchor.constraint(equalTo: view.safeAreaLayoutGuide.heightAnchor).isActive = true
        collectionView.widthAnchor.constraint(equalTo: view.safeAreaLayoutGuide.widthAnchor).isActive = true
        
        collectionView.topAnchor.constraint(equalTo: self.menuBar.bottomAnchor).isActive = true
        
        collectionView.register(AllPostsCell.self,forCellWithReuseIdentifier: cellId)
        collectionView.register(AllPostsUnderReviewCell.self,forCellWithReuseIdentifier: postsUnderReviewcell)        
        
    }
    

    func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
        for cell in collectionView.visibleCells {
              indexPath = collectionView.indexPath(for: cell)
            print(indexPath)
        }
    }


    func scrollToMenuIndex(menuIndex: Int) {
        let indexPath = NSIndexPath(item: menuIndex,section: 0)
        collectionView.scrollToItem(at: indexPath as IndexPath,at: [],animated: true)
    }

    func tabBarController(_ tabBarController: UITabBarController,didSelect viewController: UIViewController) {

        if tabBarIndex == 0 {
            if indexPath?.item == 0 {
                let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId,for: indexPath!) as! AllPostsCell
                cell.sendToTop()
            }
        }
    }
    
    func collectionView(_ collectionView: UICollectionView,numberOfItemsInSection section: Int) -> Int {
        return 2
    }

     func collectionView(_ collectionView: UICollectionView,cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
     
        var albumsCell:UICollectionViewCell?
        
        if indexPath.item == 1 {
            let underReviewCell = collectionView.dequeueReusableCell(withReuseIdentifier: postsUnderReviewcell,for: indexPath) as! AllPostsUnderReviewCell
                underReviewCell.parent = self
                return underReviewCell
        }
        
         let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId,for: indexPath) as! AllPostsCell
         cell.parent = self
         return cell
  
        
    }

在我的收藏视图单元格中

class AllPostsCell: UICollectionViewCell,UITableViewDelegate,UITableViewDataSource {
    func sendToTop() {
        dispatchQueue.main.async {
            self.layoutIfNeeded()
            self.myTableView.layoutIfNeeded()
            let indexPath = NSIndexPath(row: 0,section: 0)
            self.myTableView.scrollToRow(at: indexPath as IndexPath,at: .top,animated: true)
        }
    }
}

当我这样做时,我收到错误Terminating app due to uncaught exception 'NSRangeException',reason: 'Attempted to scroll the table view to an out-of-bounds row (0) when there are only 0 rows in section 0. 即使我在表格视图中看到行也是如此。 虽然它再次调用了我的集合视图单元格的 init 方法

那么,当我单击某个标签栏项目时,将我的 tableview 发送到顶部,在我的集合视图单元格中,有什么好的解决方案?

解决方法

解决方案:单击右侧标签栏索引后,我必须将通知从我的视图控制器发送到我的集合视图单元格。

在我的视图控制器中获取集合视图单元格的索引。

func scrollViewDidScroll(_ scrollView: UIScrollView) {
        menuBar.horizontalBarLeftAnchorConstraint?.constant = scrollView.contentOffset.x / 2
        let visibleRect = CGRect(origin: collectionView.contentOffset,size: collectionView.bounds.size)
            let visiblePoint = CGPoint(x: visibleRect.midX,y: visibleRect.midY)
            indexPath = collectionView.indexPathForItem(at: visiblePoint)
    }

点击某个标签栏项后,将通知从视图控制器发送到某个集合视图单元格。

func tabBarController(_ tabBarController: UITabBarController,didSelect viewController: UIViewController) {

        let tabBarIndex = tabBarController.selectedIndex

        if tabBarIndex == 0 {
            if indexPath?.item == 0 {
                NotificationCenter.default.post(name: Notification.Name("sendToTop"),object: nil)
            } else if indexPath?.item == 1 {
                NotificationCenter.default.post(name: Notification.Name("sendToTopUR"),object: nil)
                
            }
        }
    }

索引 0 处的集合视图单元

override init(frame: CGRect) {
        super.init(frame: frame)
   NotificationCenter.default.addObserver(self,selector: #selector(sendToTop),name: NSNotification.Name(rawValue: "sendToTop"),object: nil)
}

@objc func sendToTop() {
        DispatchQueue.main.async {
            self.layoutIfNeeded()
            self.myTableView.layoutIfNeeded()
            let indexPath = NSIndexPath(row: 0,section: 0)
            self.myTableView.scrollToRow(at: indexPath as IndexPath,at: .top,animated: true)
        }
    }