irpas技术客

iOS 多个TableView嵌套滚动处理_烟花下的孤独_ios tableview嵌套tableview

网络投稿 467

前言

此次项目中遇到了两类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


1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,会注明原创字样,如未注明都非原创,如有侵权请联系删除!;3.作者投稿可能会经我们编辑修改或补充;4.本站不提供任何储存功能只提供收集或者投稿人的网盘链接。

标签: #iOS #uitableview #嵌套