美文网首页
tableView嵌套中手势冲突问题解决

tableView嵌套中手势冲突问题解决

作者: 古月思吉 | 来源:发表于2019-01-15 13:12 被阅读0次
    demo.gif

    问题分析:
    (1)如果‘标题选择header’固定的话,还好做一些,‘标题选择header’下方放一个scrollView,scrollView内放不同的vc的view,并不会有手势冲突问题;
    (2)问题的难点在于‘标题选择header’上方还有一块区域,如果这个区域固定的话,自然好做,可是如果固定,下方列表的现实区域就会很小,体验并不好。所以需要‘标题选择header’上方区域和下方区域都能够滑动,先是整体滑动,当‘标题选择header’到顶部的时候固定住,然后继续滑动下方的区域;
    (3)根据第二点的思路,最外层,是一个tableView(A),竖向滑动,将‘标题选择header’设置为viewForHeaderInSection ,‘标题选择header’下方区域,是一个cell,cell里有scrollView(负责横向滑动,与A并不会有手势冲突),scrollView上放每个标题对应的vc的view;
    (4)关键在于每个vc上的view上,可能放tableView(B),这个tableView也是竖向滑动的,这就会与A发生手势冲突。

    • 这个手势冲突问题如何解决呢?

    1、AJScrollBaseTableView.swift 文件:

    普通的scrollView中嵌套scrollView,每次只会响应一个手势,两个scrollView之间就无法联动起来。AJScrollBaseTableView重写了shouldRecognizeSimultaneously方法,能够让tableView内部的视图也同时响应手势。

    A(最外层的tableView) 需要继承AJScrollBaseTableView

    /*
     相应联动手势(多个手势)的tableView
     */
    
    import UIKit
    
    class AJScrollBaseTableView: UITableView {
    
    }
    
    extension AJScrollBaseTableView:UIGestureRecognizerDelegate {
        
        func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
            return true
        }
        
    }
    

    _

    2、HomePageScrollController.swift 文件:
    (1)A(最外层tableView)重写scrollViewDidScroll代理方法:

    //table是否可以滑动
    var tableView_canScroll = true
    //主页最外层scrollView是否可以滑动的通知
    let kNotification_HomePageScrollController_MainScrollView_canScroll = Notification.Name("HomePageScrollController_MainScrollView_canScroll")
    
    extension HomePageScrollController:UIScrollViewDelegate {
        
        func scrollViewDidScroll(_ scrollView: UIScrollView) {
            if scrollView == tableView {
                let offSet_Y = scrollView.contentOffset.y
                if offSet_Y >= self.liveClassifyCell_Height {
                    scrollView.contentOffset = CGPoint.init(x: 0, y: self.liveClassifyCell_Height)
                    if tableView_canScroll {
                        self.tableView_canScroll = false
                        NotificationCenter.default.post(name: kNotification_HomePageScrollController_MainScrollView_canScroll, object: false)
                    }
                } else {
                    if !tableView_canScroll {//子视图没到顶部
                        scrollView.contentOffset = CGPoint.init(x: 0, y: self.liveClassifyCell_Height)
                    }
                }
                scrollView.showsVerticalScrollIndicator = tableView_canScroll ? true : false
            }
        }
    }
    

    (2)增加‘A(最外层tableView)是否可以滑动的监听’

    //tableView是否可以滑动的监听
    NotificationCenter.default.addObserver(self, selector: #selector(mainScrollViewCanScrollNotificationAction(notification:)), name: kNotification_HomePageScrollController_MainScrollView_canScroll, object: nil)
    
    deinit {
            NotificationCenter.default.removeObserver(self)
        }
    
    // MARK: - 观察者监听方法
        @objc func mainScrollViewCanScrollNotificationAction(notification:Notification) {
            guard notification.object != nil else {
                return
            }
            let canScroll = notification.object! as? Bool
            self.tableView_canScroll = canScroll ?? true
        }
    

    _

    3、HomePageAllController.swift 文件:
    (1)B(vc中的tableView)重写scrollViewDidScroll代理方法:

    //table是否可以滑动
    var tableView_canScroll = true
    
    // MARK: - UIScrollViewDelegate
    extension HomePageAllController:UIScrollViewDelegate {
    
        func scrollViewDidScroll(_ scrollView: UIScrollView) {
            if scrollView == self.tableView {
                if !tableView_canScroll {
                    scrollView.contentOffset = CGPoint.zero
                }
                if scrollView.contentOffset.y <= 0 {
                    self.tableView_canScroll = false
                    scrollView.contentOffset = CGPoint.zero
                    NotificationCenter.default.post(name: kNotification_HomePageScrollController_MainScrollView_canScroll, object: true)//到顶通知父视图改变状态
                }
                scrollView.showsVerticalScrollIndicator = tableView_canScroll ? true : false
            }
        }
    
    }
    

    (2)增加‘A(最外层tableView)是否可以滑动的监听’

    //最外层tableView是否可以滑动的监听
    NotificationCenter.default.addObserver(self, selector: #selector(mainScrollViewCanScrollNotificationAction(notification:)), name: kNotification_HomePageScrollController_MainScrollView_canScroll, object: nil)
    
    deinit {
            NotificationCenter.default.removeObserver(self)
        }
    
    // MARK: - 观察者监听方法
        @objc func mainScrollViewCanScrollNotificationAction(notification:Notification) {
            guard notification.object != nil else {
                return
            }
            let canScroll = notification.object! as? Bool
            self.tableView_canScroll = (canScroll ?? true) ? false : true
        }
    

    参考文章:
    https://www.jianshu.com/p/8bf6c2953da3

    相关文章

      网友评论

          本文标题:tableView嵌套中手势冲突问题解决

          本文链接:https://www.haomeiwen.com/subject/zgoedqtx.html