IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> iOS 多个TableView嵌套滚动处理 -> 正文阅读

[移动开发]iOS 多个TableView嵌套滚动处理

前言

此次项目中遇到了两类UITableView嵌套使用的场景,里面遇到了一些问题,所以就写此文章记录一下

UITableView 嵌套 UITableView,

首先,设置允许同时识别手势,

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

1、UITableView嵌套,从顶部下拉刷新

通过观察视图需要滑动,来控制视图的Contentoffset.y的移动,来达到效果

1.1 设置父视图

此处继承父视图即可,顶部高度可以自己设置高度,通过通知来改变滑动状态,具体滑动哪个

class UpFatherController: UIViewController {
    
    // MARK: - 1.interface
    ///是否可以滑动
    private var canScroll: Bool = true
    ///顶部高度
    public let upTop: CGFloat = 300
    
    // MARK: - 2.lift cycle
    override func viewDidLoad() {
        super.viewDidLoad()

        NotificationCenter.default.addObserver(self, selector: #selector(notiScroll), name: NSNotification.Name("up_father"), object: nil)
    }
    deinit {
        NotificationCenter.default.removeObserver(self)
    }
    
    // MARK: - 3.private methods
    ///可以滚动接受
    @objc private func notiScroll() {
        canScroll = true
    }
}

extension UpFatherController: UIScrollViewDelegate {
    func scrollViewDidScroll(_ scrollView: UIScrollView) {
        let offSetY = scrollView.contentOffset.y
        if canScroll == false {
            scrollView.contentOffset = CGPoint(x: 0, y: upTop)
        }
        if offSetY >= upTop {
            canScroll = false
            NotificationCenter.default.post(name: NSNotification.Name("up_son"), object: nil)
            scrollView.contentOffset = CGPoint(x: 0, y: upTop)
        }
    }
}

1.2设置子视图

此处继承子视图即可,通过通知来改变滑动状态,

class UpSonController: UIViewController {
    
    // MARK: 1.interface
    ///是否允许滚动
    private var canScroll: Bool = false
    
    // MARK: 2.lift cycle
    override func viewDidLoad() {
        super.viewDidLoad()

        NotificationCenter.default.addObserver(self, selector: #selector(notiScroll), name: NSNotification.Name("up_son"), object: nil)
    }
    deinit {
        NotificationCenter.default.removeObserver(self)
    }
    // MARK: 3.private methods
    ///可以滚动接受
    @objc private func notiScroll() {
        canScroll = true
    }
}

extension UpSonController: UIScrollViewDelegate {
    func scrollViewDidScroll(_ scrollView: UIScrollView) {
        let offSetY = scrollView.contentOffset.y
        if canScroll == false {
            scrollView.contentOffset = CGPoint.zero
        }
        if offSetY < 0 {
            canScroll = false
            NotificationCenter.default.post(name: NSNotification.Name("up_father"), object: nil)
        }
    }
}

1.3使用方法

1.3.1 当前ViewController 继承父视图

同时UItableView 使用 YLGestureTableView

let tableView = YLGestureTableView(frame: view.bounds), style: .plain)

1.3.2当前ViewController 继承父视图

同时UItableView 使用 YLGestureTableView

let tableView = YLGestureTableView(frame: view.bounds), style: .plain)

1.3.3 子视图我放到了cell中,当然,你也可以有其他想法

子视图vc必须放到一个 UIScrollView中,否则影响滑动

class UpCell: UITableViewCell {
     
    // MARK: - 1.lift cycle
    override func hj_setupUI() {
        super.hj_setupUI()
         
        contentView.addSubview(mainScrollView)
        mainScrollView.addSubview(bottomVC.view)
    }
    override func layoutSubviews() {
        super.layoutSubviews()
        mainScrollView.frame = CGRect(x: 0, y: 0, width: bounds.width, height: bounds.height)
        
    }
    // MARK: - 2.getter
    private lazy var mainScrollView: UIScrollView = {
        let scrollview = UIScrollView(frame: bounds)
        scrollview.contentSize = bounds.size
        scrollview.bounces = false
        
        return scrollview
    }()
    
    private lazy var bottomVC: UpBottomController = {
        let vc = UpBottomController()
        vc.view.frame = bounds
        
        return vc
    }()
}

2、UITableView嵌套,从中间下拉刷新

此处略微复杂
我划分为三种状态
0、顶部 全部可见: 可下拉,上拉变 1,默认状态
1、顶部 非全部可见:不可上拉、不可下拉
2、顶部不可见:可上拉,可下拉,下拉contentOffset.y=0 时,变1

2.1 设置父视图

此处继承父视图即可,顶部高度可以自己设置高度,通过通知来改变滑动状态,具体滑动哪个

class CenterFatherController: UIViewController {
    
    // MARK: - 1.interface
    /**
     *  0、顶部 全部可见: 可下拉,上拉变 1
     *  1、顶部 非全部可见:不可上拉、不可下拉
     *  2、顶部不可见:可上拉,可下拉,下拉contentOffset.y=0 时,变1
     */
    public var indexScroll: Int = 0
    ///顶部高度
    public let centerTop: CGFloat = 300
    // MARK: - 2.lift cycle
    override func viewDidLoad() {
        super.viewDidLoad()
        
        NotificationCenter.default.addObserver(self, selector: #selector(notiScroll), name: NSNotification.Name("center_father"), object: nil)
    }
    deinit {
        NotificationCenter.default.removeObserver(self)
    }
    // MARK: - 3.private methods
    ///可以滚动接受
    @objc private func notiScroll() {
        indexScroll = 1
    }
}
extension CenterFatherController: UIScrollViewDelegate {
    func scrollViewDidScroll(_ scrollView: UIScrollView) {
        let offSetY = scrollView.contentOffset.y
        if indexScroll == 2 {
            scrollView.contentOffset = CGPoint(x: 0, y: centerTop)
        } else if (offSetY <= 0) {
            indexScroll = 0
            NotificationCenter.default.post(name: NSNotification.Name("center_son"), object: ["index": 0])
        } else if (offSetY < centerTop) {
            indexScroll = 1
            NotificationCenter.default.post(name: NSNotification.Name("center_son"), object: ["index": 1])
        } else {
            indexScroll = 2
            NotificationCenter.default.post(name: NSNotification.Name("center_son"), object: ["index": 2])
            scrollView.contentOffset = CGPoint(x: 0, y: centerTop)
        }
    }
}

2.2设置子视图

此处继承子视图即可,通过通知来改变滑动状态,

class CenterSonController: UIViewController {
    // MARK: - 1.interface
    /**
     *  0、顶部 全部可见: 可下拉,上拉变 1
     *  1、顶部 非全部可见:不可上拉、不可下拉
     *  2、顶部不可见:可上拉,可下拉,下拉contentOffset.y=0 时,变1
     */
    public var indexScroll: Int = 0
    // MARK: - 2.lift cycle
    override func viewDidLoad() {
        super.viewDidLoad()
   
        NotificationCenter.default.addObserver(self, selector: #selector(notiScroll), name: NSNotification.Name("center_son"), object: nil)
    }
    deinit {
        NotificationCenter.default.removeObserver(self)
    }
    // MARK: - 3.private methods
    ///可以滚动接受
    @objc private func notiScroll(_ noti: Notification) {
        if let object = noti.object as? [String: Int] {
            let index = object["index"] ?? 0
            indexScroll = index
        }
    }
}

extension CenterSonController: UIScrollViewDelegate {
    func scrollViewDidScroll(_ scrollView: UIScrollView) {
        let offsetY = scrollView.contentOffset.y
        switch indexScroll {
        case 0:
            if offsetY > 0 {
                indexScroll = 1
                scrollView.setContentOffset(CGPoint.zero, animated: false)
                NotificationCenter.default.post(name: NSNotification.Name("center_father"), object:nil)
            }
        case 1:
            scrollView.setContentOffset(CGPoint.zero, animated: false)
        default:
            if offsetY < 0 {
                indexScroll = 1
                scrollView.setContentOffset(CGPoint.zero, animated: false)
                NotificationCenter.default.post(name: NSNotification.Name("center_father"), object: nil)
            }
        }
        
    }
}

2.3使用方法

使用方法完全和1.3一致,请看上文

demo

嗯,感觉这个东西逻辑有点头疼,而且我此篇文章描述的很烂,文章我尽量改吧,大家还是看demo吧,demo上展示的清清楚楚的
demo 传送门

嗯,由于上面giee开源一直有问题,可以来下面CSDN上下载链接下载,免积分的
HJScrollView

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2022-05-21 19:06:35  更:2022-05-21 19:07:01 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 1:58:07-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码