效果(两种方法)
图一 参考大牛用一个中间类来观察两者的contentoffset
图二 白嫖别人轮子大法
方法一:
重写bottomscrollview和toptableview的contentoffset的属性观察器
bottom:
override var contentOffset: CGPoint {
didSet {
if contentOffset.y != oldValue.y {
//每次滑动tableview看着没动,其实还是有一点点细微的变化的,每次动一点点,都会通过runloop机制赋值0;所以总是 !=oldValue.y
//下层scrollView滑动,自己保持headview的最大值不动,滑动上面的tableview.
if obstext.topOffset.y > 0 {
// 上层的scrollView滑动,则下层的scrollView保持最大滑动距离
contentOffset.y = obstext.maxOffsetY
} else {
//否则,上层不动,下层滑动
}
//同步offset到上下文
obstext.bottomOffset = contentOffset
//底部一直上移,bottomoffset一直增加,增加到图片高度时候才能进入上面的循环(topscrollview里面的函数才能出来并给top赋值)
}
}
}
top:
override var contentOffset: CGPoint {
didSet {//每次滑动tableview看着没动,其实还是有一点点细微的变化的,每次动一点点,都会通过runloop机制赋值0;所以总是 !=oldValue.y
if contentOffset.y != oldValue.y {
//上层滑动
guard let obstext = obstext else { return }
if obstext.bottomOffset.y < obstext.maxOffsetY {
//下层的offset < 下层可滑动最大值,说明下层还需要滑动,上层不动offset为0
contentOffset.y = 0
}
//这上面contentOffset.y一直是0,直到tableview到顶部,退出上面的循环,给innerOffset赋值contentOffset(图片的高度)
//不管怎么样,滑动即同步offset到上下文
obstext.topOffset = contentOffset
}
}
}
观察类
//创建一个观察者类,并让bottom和top引用同一个对象,这样就可以保证同时检测对方的contentoffset
class obs {
var maxOffsetY: CGFloat = 0 //上层最大的滑动距离
var topOffset: CGPoint = CGPoint.zero //下层offset
var bottomOffset: CGPoint = CGPoint.zero //上层offset
}
在bottomscrollview的初始化器当中给bottom和toptableview引用同一个对象
override init(frame: CGRect) {
topScrollView = TopScroll(frame: CGRect(x: 0, y: 280, width: frame.size.width, height: frame.size.height))
//创建上下文,并让两个scrollView都持有
obstext = obs()
obstext.maxOffsetY = 200
topScrollView.obstext = obstext
super.init(frame: frame)
if #available(iOS 11.0, *) {
contentInsetAdjustmentBehavior = .never
}
topScrollView.register(UITableViewCell.self, forCellReuseIdentifier: "UITableViewCell")
addSubview(header)
addSubview(topScrollView)
topScrollView.dataSource = self
contentSize = CGSize(width: bounds.width, height: topScrollView.frame.maxY)
}
方法二:直接用ParallaxHeade 几行代码即可实现
func configTableViewHeader() {
tableView.parallaxHeader.view = headerView
tableView.parallaxHeader.height = 290.fit
tableView.parallaxHeader.minimumHeight = navigationBarY
tableView.parallaxHeader.mode = .fill
}