PYScrollToolBarView(解决了很多手势冲突)


声明:本文转载自https://my.oschina.net/LiPengYue/blog/1603082,转载目的在于传递更多信息,仅供学习交流之用。如有侵权行为,请联系我,我会及时删除。

scrollToolBarView演示.gif

OC: 工具类下载 pod 'PYToolBarScrollView' swift:工具下载 pod 'PYToolBarScrollView_Swift'

#一、简介 这个工具写了很久,一直不满意,换了n种方法,最后毛瑟顿开,用最平常的知识解决了问题。虽然很简单,但很巧妙。

  1. 适用结构: 1. 顶部有一个topView 2. 中间有个选项栏(toolBarView) 3. 底部有scrollVIew的集合(UITableView,UICollectionView)
  2. 效果: 1. 随着底部的scrollView的滚动,topView与toolBarView也跟着上下滚动。 2. toolBarView的到顶部的时候悬停
  3. 主要解决的问题: 1. 解决了根据底部scrollView的不同contentOffset设置topView与toolBarView的高度问题 2. 解决了中间toolBar悬停的问题 3. 解决了底部scrollView左右滑动的问题

#二、 知识点

  1. scrollView的一些知识,看这里
  2. 关于toolBarView的封装,看这里
  3. CoreGraphics的知识,看这里

#三、工具结构 整体由最低层的ScrollViewtopViewmidToolBarViewbottomScrollView、还有bottomScrollViews组成 1. 主要的包含关系

  1. 最底层scrollVIew 1.在他的上面有topView,midToolBarView,bottomScrollView,bottomScrollViewArray 1. 这样的话就可以做到让bottomViews,midToolBarView,topView,一起上下滚动,只修改最低层的scrollView的contentOffset就可以了
  2. 顶部的topView 为了扩展性,这个顶部的topView是由外部传进来
  3. 中间的toolBarView 1. 这个是选项栏,也就是点击相应的按钮,底部的BottomScrollView就会相应相应的界面 2. toolBarView的点击事件有传出到外部 3. toolBarView的titleArray应该与BottomScrollView中的bottomScrollViewArray数目一致 4. 点击滑动到相应的ScrollView界面 5. 与下部的BottomScrollView滑动不会产生冲突
  4. 底部的BottomScrollView 1. 主要是承接bottomScrollViewArray,让他们依次排列,并且可以左右滚动 2. 设置了分页,每次到新的页面都会向外发送index和ScrollView消息 3. 对数组长度进行了判断,避免了数组越界造成的崩溃
  5. bottomScrollViewArray 1. 这个是外部传入的scrollView 的数组 2. 内部监听了bottomScrollViewArray元素的contentOffset,对self.contentOffset进行设置,达到联动效果

#四、遇到的问题 1. 当底部有多个scrollView或者多个view的时候,解决底部scrollView的contentOffset不一致造成的self.contentOffset的滑动突兀的问题 造成这个问题的根本原因是:

  1. 我在外部传入BottomScrollViewArray的时候会先判断其是否为scrollView,如果是scrollView,那么监听了scrollView的contentOffset,并根据scrollView的contentOffset,改变self.contentOffset
  2. 在监听的会调函数中,根据监听到的ScrollView的滚动的contentOffset改变self.contentOffset
  3. 如果,bottomScrollViewArray中有A、B两个scrollView做下面操作 1. A滚动30的距离(这时候self.contentOffset.y跟随A变成了30) 2. 现在切换到了B,这时候就会出现问题 3. 因为B的contentOffset.y为0,而self.contentOffset为30,当你在滑动B的时候,B的contentOffset发生改变,那么将对self.contentOffset重新赋值,这时候,B的contentOffset.y为0,而self.contentOffset.y为30,则self.contentOffset会直接变成0

解决方案:

  1. 添加了一个OffsetY变量。 在将要切换的底部的scrollView的时候对A与B进行contentOffset.y差值计算。 在B滑动的时候把差值也算入到self.contentOffset中。 在滑动到顶部,或者底部的时候,对offsetY进行清零 但是还是有缺陷,比如A的contentOffset.y 为0,而self.contentOffset.y已经到最大,那么切换到A,向下拉,也会有self直接掉下来的突兀感

代码:

 ///布局bottomScrollView的subView (把subView添加到了bottomScrollViewView里面)     private func setupBottomScrollViewSubView(_ contentOffsetY: CGFloat) {         for index: NSInteger in 0 ..< self.bottomViewArray.count {             //布局subview             let view: UIView = self.bottomViewArray[index]             self.bottomScrollView.addSubview(view)             view.frame = CGRect(x: kToolBarScrollViewW * CGFloat(index), y:0, width: kToolBarScrollViewW, height: kBottomScrollViewH + contentOffsetY)             //如果要是是ScrollView的子类那么监听contentOffset             if view is UIScrollView {                 let scrollView: UIScrollView = view as! UIScrollView                 scrollView.addObserver(self, forKeyPath: "contentOffset", options: .new, context: nil)             }         }     }   ///通知的方法     override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {         if keyPath == "contentOffset" { //            print(change?[NSKeyValueChangeKey.newKey] ?? "----- 没有纸")             let scrollView: UIScrollView = object as! UIScrollView             //获取偏移量             let newValue: CGPoint = change?[NSKeyValueChangeKey.newKey] as! CGPoint             self.newValue = newValue;             //改变scrollView偏移的位置             if scrollView.contentOffset.y <= 0{                 if newValue.y < 0 {                     self.offset = 0                 }                 self.contentOffset = CGPoint(x: 0, y: 0)             }             if scrollView.contentOffset.y >= self.kTopViewH {                 if newValue.y > self.kTopViewH {                     self.offset = 0                 }                   self.contentOffset = CGPoint(x: 0, y: self.kTopViewH)             } //            let isScrollBottom = Int(scrollView.contentSize.height - self.contentOffset.y) <= Int(scrollView.frame.size.height);             if scrollView.contentSize.height <= scrollView.frame.size.height + kTopViewH {                    let insertY = scrollView.frame.size.height + kTopViewH - scrollView.contentSize.height                    scrollView.contentInset = UIEdgeInsetsMake(0, 0, insertY, 0)             }else{                 scrollView.contentInset = UIEdgeInsetsMake(0, 0, 0, 0)             }             self.contentOffset = CGPoint(x: 0, y: newValue.y + self.offset)         }     } 

2. 当前显示的scrollView的contentSize滑动不到顶部,底部的scrollView就会显示不全 解决方法: 在滚动的时候判断,当前的scrollView的滑动范围,是否足以让self滑动到顶部

 if scrollView.contentSize.height <= scrollView.frame.size.height + kTopViewH {                                  let insertY = scrollView.frame.size.height + kTopViewH - scrollView.contentSize.height                                  scrollView.contentInset = UIEdgeInsetsMake(0, 0, insertY, 0)             }else{                 scrollView.contentInset = UIEdgeInsetsMake(0, 0, 0, 0)             }                          self.contentOffset = CGPoint(x: 0, y: newValue.y + self.offset)         } 

#更新:2017.11.15 1. PYMidView的扩展

  1. 对中间的toolBarView的扩展性,进行了修复。添加了一个PYMidView(继承自UIView),他有个代理属性,var delegate: PYToolBarViewProtocol?要求实现一个方法,返回对应的toolBarView,
  2. 事实上,你只要继承PYMidView,然后在里面布局子控件,并且,把代理属性设置成自己,实现代理方法,就可以完美适应任何产品需求。

*代码

import UIKit class PYMidView: UIView {     required init?(coder aDecoder: NSCoder) {         fatalError("init(coder:) has not been implemented")     }     override init(frame: CGRect) {         super.init(frame: frame)     }     var delegate: PYToolBarViewProtocol?     private var isFirstSetToolBarUI: Bool = true          override func layoutSubviews() {         if isFirstSetToolBarUI {             self.delegate?.registerToolBarView().displayUI()             layoutIfNeeded()             isFirstSetToolBarUI = false         }     } }  

#更新:2018.1.5 进行了重构,具体思路差不多,只是提高了兼容性,与遗留bug的修复。 下一步,准备兼容web 滑动的监听。具体看代码:

OC: 工具类下载 pod 'PYToolBarScrollView' swift:工具下载 pod 'PYToolBarScrollView_Swift'

本文发表于2018年01月05日 18:32
(c)注:本文转载自https://my.oschina.net/LiPengYue/blog/1603082,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责。如有侵权行为,请联系我们,我们会及时删除.

阅读 1699 讨论 0 喜欢 0

抢先体验

扫码体验
趣味小程序
文字表情生成器

闪念胶囊

你要过得好哇,这样我才能恨你啊,你要是过得不好,我都不知道该恨你还是拥抱你啊。

直抵黄龙府,与诸君痛饮尔。

那时陪伴我的人啊,你们如今在何方。

不出意外的话,我们再也不会见了,祝你前程似锦。

这世界真好,吃野东西也要留出这条命来看看

快捷链接
网站地图
提交友链
Copyright © 2016 - 2021 Cion.
All Rights Reserved.
京ICP备2021004668号-1