iOS scrollview 嵌套tableview 手势解决

结果:scrollview 滑动到一定高度固定,tableview可以上下滑动,当tableview滑动到contentOffset.y为0的时候tableview不滑动,然后scrollview可以滑动。滑动到初始位置的时候不影响tableview刷新!

只是讲一下思路,demo等忙过这一段时间的话 会抽离出来:

  1. 首先scrollview要自定义一个自己的集成UIScrollvuew 遵循手势的代理 UIGestureRecognizerDelegate
 import UIKit
  
 class ZCNestScrollview: UIScrollView,UIGestureRecognizerDelegate     {
    func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith    otherGestureRecognizer: UIGestureRecognizer) -> Bool {
        
        return true
    }

    /*
    // Only override draw() if you perform custom drawing.
    // An empty implementation adversely affects performance during animation.
    override func draw(_ rect: CGRect) {
        // Drawing code
    }
    */

  }

2.使用的scrollivew 的控制器内遵循UIScrollViewDelegate
实现代理方法
func scrollViewDidScroll(_ scrollView: UIScrollView)

func scrollViewDidScroll(_ scrollView: UIScrollView) {
        // 设置滑动的高度
        let headH = xxxx 
        // 这里面是嵌套的子控制器的通知方法 只要控制在scrollview滑动的时候子类的tableview是否可以滑动
        let notificationName = Notification.Name(rawValue: "subScrollProjectSubDetialIsCanScroll")
      // scrollview的偏移量
        let contentY = scrollView.contentOffset.y
        // 这个是父类的自定义的一个属性 判断是否可以滑动
        if isCanScroll{
            // 在这个区域内是scrollview滑动的范围
            if contentY > 0.0 && Int(contentY) < Int(headH){  // 滑动区域
                // 禁止子类滑动    0 1 2 上 中 下 代表scrollview停留的位置
                NotificationCenter.default.post(name: notificationName, object: ["status":false,
                                                                                            "location":1])

            }else{  // 禁止滑动区域
                if contentY <= 0{
                    scrollView.contentOffset = CGPoint(x: 0, y: 0);
                    NotificationCenter.default.post(name: notificationName, object: ["status":true,
                               "location":2])   // 初始状态

                }else{
                    scrollView.contentOffset = CGPoint(x: 0, y: headH);
                    NotificationCenter.default.post(name: notificationName, object: ["status":true,
                               "location":0])   // 滑动到顶部
                }

                // 允许子类滑动
            }
        }else{
            // 不能滑动的时候 也分两种情况  就是当到顶部的时候 和  在 在底部 子类向下滑动的时候
            if contentY < 0{
                scrollView.contentOffset = CGPoint(x: 0, y: 0);
            }else{
                scrollView.contentOffset = CGPoint(x: 0, y: headH);
            }
            
        }
        
    }

  1. 关键是子类的处理
    子类的通知 接受父类的传递的值和状态
 let notificationName = Notification.Name(rawValue: "subScrollProjectSubDetialIsCanScroll")
        NotificationCenter.default.rx
        .notification(notificationName)
        .takeUntil(self.rx.deallocated)
        .share()
        .subscribe(onNext: { (notification) in
            // 判断是否可以滑动了
            // 给父类的scrollview 的滑动加一个开关
            let dic = notification.object as! Dictionary<String, Any>
            self.isScrollSub = dic["status"] as! Bool
            self.moveLocation = dic["location"] as! Int
            
            
        }).disposed(by: disposeBag)

override func scrollViewDidScroll(_ scrollView: UIScrollView) {
            
            let contentY = scrollView.contentOffset.y
            let notificationName = Notification.Name(rawValue: "notificationScroll")
            if isScrollSub{  
                if contentY > 0{  // 证明不是在初始状态  实在tableview可滑动的区域
                    //  moveLocation 是自定义的属性记录来自父类通知的时候的值
                    if moveLocation == 0{   // 顶部
                        NotificationCenter.default.post(name: notificationName, object: false)

                    }else if moveLocation == 2{  // scrollview的初始状态
                        NotificationCenter.default.post(name: notificationName, object: true)
                        scrollView.contentOffset = CGPoint.zero
                        isScrollSub = false
                    }
                }else{
                    if moveLocation == 0{
                        NotificationCenter.default.post(name: notificationName, object: true)
                        scrollView.contentOffset = CGPoint.zero
                        isScrollSub = false
                    }
                    
                }
            }
            
            else{
            if moveLocation != nil{
                 NotificationCenter.default.post(name: notificationName, object: true)
                scrollView.contentOffset = CGPoint.zero
                isScrollSub = false
              }
            }
               
    }
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容