前言
此次项目中遇到了两类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 {
private var canScroll: Bool = true
public let upTop: CGFloat = 300
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: #selector(notiScroll), name: NSNotification.Name("up_father"), object: nil)
}
deinit {
NotificationCenter.default.removeObserver(self)
}
@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 {
private var canScroll: Bool = false
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: #selector(notiScroll), name: NSNotification.Name("up_son"), object: nil)
}
deinit {
NotificationCenter.default.removeObserver(self)
}
@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 {
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)
}
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 {
public var indexScroll: Int = 0
public let centerTop: CGFloat = 300
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: #selector(notiScroll), name: NSNotification.Name("center_father"), object: nil)
}
deinit {
NotificationCenter.default.removeObserver(self)
}
@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 {
public var indexScroll: Int = 0
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: #selector(notiScroll), name: NSNotification.Name("center_son"), object: nil)
}
deinit {
NotificationCenter.default.removeObserver(self)
}
@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
|