美文网首页
Swift笔记-UITableView嵌套滑动手势传递问题

Swift笔记-UITableView嵌套滑动手势传递问题

作者: 岁变 | 来源:发表于2020-05-22 17:00 被阅读0次
    RPReplay_Final1590134200.gif

    UITableView上添加TableView,方便叙述将两个TableView编号,底层TableView为1,上层的TableView为2。

    如图:
    下拉时,当1未滑动到指定位置时2不单独滑动,跟随1滑动,当1滑动到指定位置时1不动2进行单独滑动。
    上拉时,当2未滑动到顶部,1保持不动,当2滑动到顶部时1跟随着滑动。

    首先

    我们需要让两个1跟2同时响应滑动的手势
    这样的话就需要在TableView签订手势识别代理

    <UIGestureRecognizerDelegate>
    

    实现代理方法

        func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
            return true
        }
    

    Simultaneously:同时的
    这个方法意思是,是否允许多个手势识别器同时识别,一个控件的手势识别后,是否阻断手势识别继续向下传递,默认为false,如果return true,响应者链上层触发手势后,如果下层也添加了相同手势,则会同样响应手势。

    创建传递手势的TableView

    import UIKit
    
    class GestureTableView: UITableView, UIGestureRecognizerDelegate {
        func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
            return true
        }
    }
    

    然后

    设计思路是在scrollViewDidScroll的代理方法中进行contentOffset的位置判断,处理两个TableView的滑动状态。

    注意的是,处理TableView保持不动的方法不要用

    tableView.isScrollEnable,
    

    当滑动速度快时,位置判断会不生效。
    改用

    tableView.contentOffset = CGPoint(x: 0, y: X)
    

    时时设置TableView的位置来控制滑动与停止。

    另外两个TableView的状态信息需要共享,这里我用到了通知中心,互相发送状态改变的信号,作出响应的处理操作。

    代码里有详细的注释:

    import UIKit
    
    
    class TableViewQTController: BaseViewController, UITableViewDelegate, UITableViewDataSource {
        
        
        ///tableview是否可以滑动
        var canScroll: Bool = true
        
        lazy var tableView: GestureTableView = {
            let table = GestureTableView()
            table.backgroundColor = .clear
            table.delegate = self
            table.dataSource = self
            //取消tableView底部的线条
            table.separatorStyle = .none
            return table
        }()
        
        
        override func setViews() {
            view.addSubview(tableView)
            
            tableView.snp.makeConstraints {
                $0.top.equalToSuperview().offset(statusBarH + 44)
                $0.left.right.bottom.equalToSuperview()
            }
            
            tableView.register(TableQTTitleTableCell.self, forCellReuseIdentifier: "TableQTTitleTableCell")
            tableView.register(TableInTabelCell.self, forCellReuseIdentifier: "TableInTabelCell")
            
            addCenterNotification()
        }
        
        
        //注册通知中心 等待下层tabel发来状态改变
        func addCenterNotification() {
            NotificationCenter.default.addObserver(self, selector: #selector(notificationAction), name: NSNotification.Name(rawValue: "botTable"), object: nil)
            
        }
        
        //收到通知进行操作
        @objc func notificationAction() {
            //收到下层table的通知,上层table可以开始滑动
            self.canScroll = true
        }
        
        deinit {
            NotificationCenter.default.removeObserver(self, name: NSNotification.Name(rawValue: "botTable"), object: nil)
        }
        
        //MARK: - Delegate
        
        func scrollViewDidScroll(_ scrollView: UIScrollView) {
            
            let y = scrollView.contentOffset.y
            
            if !canScroll {
                //上层table保持不动
                self.tableView.contentOffset = CGPoint(x: 0, y: 200)
            }
            
            /**
             当contentOffset.y大于200时
             上层的Table保持不动
             并发送通知让下层table动
             */
            if y >= 200 {
                self.canScroll = false
                self.tableView.contentOffset = CGPoint(x: 0, y: 200)
                NotificationCenter.default.post(name: NSNotification.Name(rawValue: "topTable"), object: nil)
            }
        }
        
        
        func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
            if indexPath.row == 3 {
                return S_H - statusBarH - bottomBarH - 100 - 44
            }
            return 100
        }
        
        
        func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
            return 4
        }
        
        func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
            
            if indexPath.row == 3 {
                let cell = tableView.dequeueReusableCell(withIdentifier: "TableInTabelCell") as! TableInTabelCell
                return cell
            } else {
                let cell = tableView.dequeueReusableCell(withIdentifier: "TableQTTitleTableCell") as! TableQTTitleTableCell
                cell.titlab.text = "这是第\(indexPath.row)个cell"
                if indexPath.row == 0 {
                    cell.contentView.backgroundColor = .red
                }
                if indexPath.row == 1 {
                    cell.contentView.backgroundColor = .green
                }
                if indexPath.row == 2 {
                    cell.contentView.backgroundColor = .yellow
                }
                
                return cell
            }
        }
    }
    
    
    
    
    class TableQTTitleTableCell: BaseTableViewCell {
        
        let titlab = UILabel()
        
        override func setViews() {
            
            titlab.textColor = .black
            titlab.font = SFONT(15)
            contentView.addSubview(titlab)
            
            titlab.snp.makeConstraints {
                $0.left.equalToSuperview().offset(20)
                $0.centerY.equalToSuperview()
            }
        }
    }
    
    class TableInTabelCell: BaseTableViewCell, UITableViewDataSource, UITableViewDelegate {
        
        var canSroll: Bool = false
        
        lazy var tableView: GestureTableView = {
            let table = GestureTableView()
            table.backgroundColor = .clear
            table.delegate = self
            table.dataSource = self
            table.separatorStyle = .none
            return table
        }()
        
        override func setViews() {
            
            tableView.register(TableQTTitleTableCell.self, forCellReuseIdentifier: "TableQTTitleTableCell")
            
            contentView.addSubview(tableView)
            tableView.snp.makeConstraints {
                $0.edges.equalToSuperview()
            }
            
            addCenterNotification()
        }
        
        //注册通知中心 等待上层table发来通知
        func addCenterNotification() {
            NotificationCenter.default.addObserver(self, selector: #selector(notificationAction), name: NSNotification.Name(rawValue: "topTable"), object: nil)
            
        }
        
        //收到通知进行操作
        @objc func notificationAction() {
            //上层tabel滑动到指定位置后发来通知,下层table可以开始滑动了
            self.canSroll = true
        }
    
        
        func scrollViewDidScroll(_ scrollView: UIScrollView) {
            let y = scrollView.contentOffset.y
            
            if !canSroll {
                //保持不动的操作
                scrollView.contentOffset = CGPoint.zero
            }
            /**
             当contentOffset.y <= 0 即table滑动到顶部时
             table保持不动并向上层table发送通知
             让其可以开始滑动
             */
            
            if y <= 0 {
                self.canSroll = false
                scrollView.contentOffset = CGPoint.zero
                NotificationCenter.default.post(name: NSNotification.Name(rawValue: "botTable"), object: nil)
            }
            
        }
        
        deinit {
            NotificationCenter.default.removeObserver(self, name: NSNotification.Name(rawValue: "topTable"), object: nil)
        }
        
        
        func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
            return 60
        }
        
        func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
            return 20
        }
        
        func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
            let cell = tableView.dequeueReusableCell(withIdentifier: "TableQTTitleTableCell") as! TableQTTitleTableCell
            cell.contentView.backgroundColor = .lightGray
            cell.titlab.text = "第\(indexPath.row)个"
            return cell
        }
    }
    
    

    相关文章

      网友评论

          本文标题:Swift笔记-UITableView嵌套滑动手势传递问题

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