嵌套scrollview, 实现tab吸顶,页面左右滑动切换,上滑tab吸顶,自己研究了一下,下面看看效果
?
创建一些基本UI?
/// 屏幕宽度
let Screen_Width = UIScreen.main.bounds.width
?
/// 屏幕高度
let Screen_Height = UIScreen.main.bounds.height
?
?
class JWDoubleScrollViewVC: UIViewController {
?
? ? var headView:UIView?
? ? var slideLine:UILabel?
? ? var segBtns = [UIButton]()
? ? var tableviews = [UITableView]()
?? ?
? ? let segWidth = Screen_Width / 4
? ? let headViewH = 300
? ? let segH = 40
? ? var currentTabIndex = 0
? ? var distance:Int{
? ? ? ? get{
? ? ? ? ? ? return headViewH - segH
? ? ? ? }
? ? }
?? ?
? ? fileprivate var rootScrollView:MyScrollView={
? ? ? ? let scrollview = MyScrollView.init()
? ? ? ? scrollview.backgroundColor = UIColor.white
? ? ? ? scrollview.bounces = false
? ? ? ? scrollview.showsVerticalScrollIndicator = false
? ? ? ? scrollview.showsHorizontalScrollIndicator = false
? ? ? ? return scrollview
? ? }()
?? ?
? ? fileprivate var containerScrollView:UIScrollView = {
? ? ? ? let scrollview = UIScrollView.init()
? ? ? ? scrollview.backgroundColor = UIColor.white
? ? ? ? scrollview.bounces = false
? ? ? ? scrollview.isPagingEnabled = true
? ? ? ? scrollview.showsVerticalScrollIndicator = false
? ? ? ? scrollview.showsHorizontalScrollIndicator = false
? ? ? ? return scrollview
? ? }()
?? ?
? ? override func viewDidLoad() {
? ? ? ? super.viewDidLoad()
?
? ? ? ? // Do any additional setup after loading the view.
? ? ? ? self.view.backgroundColor = UIColor.white
?
? ? ? ? self.setupUI()
? ? }
?? ?
? ? override func viewWillAppear(_ animated: Bool) {
? ? ? ? super.viewWillAppear(animated)
? ? ? ? rootScrollView.isScrollEnabled = true
? ? }
?? ?
?? ?
? ? func setupUI() {
?? ? ? ?
? ? ? ? rootScrollView.delegate = self
? ? ? ? containerScrollView.delegate = self
?? ? ? ?
? ? ? ? let rootView = UIView.init()
? ? ? ? self.view.addSubview(rootView)
? ? ? ? rootView.snp.makeConstraints { (make) in
? ? ? ? ? ? make.top.equalTo(90)
? ? ? ? ? ? make.left.right.bottom.equalToSuperview()
? ? ? ? }
? ? ? ? rootView.layoutIfNeeded()
?? ? ? ?
? ? ? ? rootView.addSubview(rootScrollView)
? ? ? ? rootScrollView.snp.makeConstraints { (make) in
? ? ? ? ? ? make.edges.equalTo(rootView)
? ? ? ? }
? ? ? ? rootScrollView.layoutIfNeeded()
?? ? ? ?
? ? ? ? //headview
? ? ? ? headView = UIView.init()
? ? ? ? headView?.backgroundColor = UIColor.blue
? ? ? ? rootScrollView.addSubview(headView!)
? ? ? ? headView?.snp.makeConstraints({ (make) in
? ? ? ? ? ? make.top.left.right.equalToSuperview()
? ? ? ? ? ? make.width.equalTo(Screen_Width)
? ? ? ? ? ? make.height.equalTo(headViewH)
? ? ? ? })
? ? ? ? headView?.layoutIfNeeded()
?? ? ? ?
? ? ? ? rootScrollView.addSubview(containerScrollView)
? ? ? ? containerScrollView.snp.makeConstraints { (make) in
? ? ? ? ? ? make.left.right.bottom.equalToSuperview()
? ? ? ? ? ? make.top.equalTo(headView!.snp.bottom)
? ? ? ? ? ? make.width.equalTo(Screen_Width)
? ? ? ? ? ? make.height.equalTo(rootScrollView.frame.height)
? ? ? ? }
? ? ? ? containerScrollView.layoutIfNeeded()
?? ? ? ?
? ? ? ? //tab背景view
? ? ? ? let btnContainerView = UIView.init()
? ? ? ? rootScrollView.addSubview(btnContainerView)
? ? ? ? btnContainerView.snp.makeConstraints { (make) in
? ? ? ? ? ? make.left.right.equalToSuperview()
? ? ? ? ? ? make.height.equalTo(segH)
? ? ? ? ? ? make.bottom.equalTo(headView!.snp.bottom)
? ? ? ? ? ? make.width.equalTo(Screen_Width)
? ? ? ? }
? ? ? ? btnContainerView.layoutIfNeeded()
?? ? ? ?
? ? ? ? for i in 0...3 {
? ? ? ? ? ? //添加Tab
? ? ? ? ? ? let button = self.createButton(i)
? ? ? ? ? ? btnContainerView.addSubview(button)
? ? ? ? ? ? segBtns.append(button)
?? ? ? ? ? ?
? ? ? ? ? ? //添加tableview
? ? ? ? ? ? let tableview = self.createTableView(i)
? ? ? ? ? ? containerScrollView.addSubview(tableview)
? ? ? ? ? ? tableviews.append(tableview)
? ? ? ? }
?? ? ? ?
? ? ? ? //tab底部横线
? ? ? ? slideLine = UILabel.init(frame: CGRect.init(x: 0, y: CGFloat(segH - 6), width: segWidth, height: 4))
? ? ? ? slideLine?.backgroundColor = .white
? ? ? ? slideLine?.layer.cornerRadius = 4/2
? ? ? ? slideLine?.layer.masksToBounds = true
? ? ? ? btnContainerView.addSubview(slideLine!)
?? ? ? ?
? ? ? ? //设置scrollview滑动区域
? ? ? ? containerScrollView.contentSize = CGSize.init(width: CGFloat(segBtns.count) * Screen_Width, height: 0)
? ? }
?? ?
? ? /**
? ? 创建Tab
?? ? */
? ? func createButton(_ i:Int) -> UIButton {
? ? ? ? let button = UIButton.init(type: .custom)
? ? ? ? button.frame = CGRect.init(x: CGFloat(i)*segWidth, y: 0, width: segWidth, height: CGFloat(segH))
? ? ? ? button.setTitle(String.init(format: "第%i个", i), for: .normal)
? ? ? ? button.titleLabel?.textAlignment = .center
? ? ? ? button.tag = 1000 + i
? ? ? ? button.backgroundColor = .red
? ? ? ? button.setTitleColor(UIColor.white, for: .normal)
? ? ? ? button.setTitleColor(UIColor.yellow, for: .selected)
? ? ? ? button.addTarget(self, action: #selector(segAction(button:)), for:.touchUpInside)
? ? ? ? return button
? ? }
?? ?
? ? /**
?? ? 创建tableview
?? ? */
? ? func createTableView(_ i:Int) ->UITableView{
? ? ? ? let tableView = UITableView.init(frame: .zero, style: .plain)
? ? ? ? tableView.frame = CGRect.init(x: CGFloat(i)*Screen_Width, y: 0, width: Screen_Width, height: rootScrollView.frame.height - CGFloat(segH))
? ? ? ? tableView.delegate = self
? ? ? ? tableView.dataSource = self
? ? ? ? tableView.backgroundColor = .green
? ? ? ? tableView.sectionHeaderHeight = 0
? ? ? ? tableView.sectionFooterHeight = 0
? ? ? ? //tableView.bounces = false
? ? ? ? tableView.backgroundColor = UIColor.white
? ? ? ? tableView.register(UITableViewCell.classForCoder(), forCellReuseIdentifier: NSStringFromClass(UITableViewCell.classForCoder()))
? ? ? ? return tableView
? ? }
?? ?
?
? ? /**
?? ? 滑动tab切换
?? ? */
? ? func sliderAnimationWithTag(tag:Int){
?? ? ? ?
? ? ? ? rootScrollView.isScrollEnabled = true
?? ? ? ?
? ? ? ? currentTabIndex = tag;
?? ? ? ?
? ? ? ? for item in segBtns.enumerated() {
? ? ? ? ? ? let button = item.element
? ? ? ? ? ? button.isSelected = false
? ? ? ? }
?? ? ? ?
? ? ? ? let button = segBtns[tag]
? ? ? ? button.isSelected = true
?? ? ? ?
? ? ? ? UIView.animate(withDuration: 0.25) { [weak self] in
? ? ? ? ? ? self!.slideLine?.center = CGPoint.init(x: CGFloat(button.center.x), y: CGFloat((self!.slideLine?.center.y)!))
? ? ? ? }
?? ? ? ?
? ? }
?? ?
? ? @objc func segAction(button:UIButton) {
?? ? ? ?
? ? ? ? //滑动到指定页面
? ? ? ? containerScrollView.setContentOffset(CGPoint.init(x:CGFloat(button.tag - 1000) * Screen_Width, y: 0), animated: true)
?
? ? }
?? ?
? ? //tablview是否可以滑动
? ? func canTableViewScroll() -> Bool {
? ? ? ? return rootScrollView.contentOffset.y >= CGFloat(self.distance)
? ? }
?? ?
? ? //主rootscrollview是否可以滑动
? ? func canRootViewScroll() -> Bool {
? ? ? ? return tableviews[currentTabIndex].contentOffset.y <= 0
? ? }
?
? ? /*
? ? // MARK: - Navigation
?
? ? // In a storyboard-based application, you will often want to do a little preparation before navigation
? ? override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
? ? ? ? // Get the new view controller using segue.destination.
? ? ? ? // Pass the selected object to the new view controller.
? ? }
? ? */
?
}
?
此部分处理嵌套scrollview手势页面交互
extension JWDoubleScrollViewVC:UIScrollViewDelegate{
?? ?
?? ?
? ? func scrollViewDidScroll(_ scrollView: UIScrollView) {
?? ? ? ?
? ? ? ? if scrollView.isKind(of: UITableView.classForCoder()){ //tableview
?? ? ? ? ? ?
? ? ? ? ? ? let offY = tableviews[currentTabIndex].contentOffset.y;
? ? ? ? ? ? if offY < 0 {
? ? ? ? ? ? ? ? tableviews[currentTabIndex].contentOffset = .zero;//去掉tableview上方弹性
? ? ? ? ? ? }
?? ? ? ? ? ?
? ? ? ? ? ? guard !canTableViewScroll() else {
? ? ? ? ? ? ? ? return
? ? ? ? ? ? }
?? ? ? ? ? ?
? ? ? ? ? ? scrollView.contentOffset.y = 0
?
? ? ? ? }else if scrollView === rootScrollView{? //主scrollview
?? ? ? ? ? ?
?? ? ? ? ? ?
? ? ? ? ? ? guard !canRootViewScroll() else {
? ? ? ? ? ? ? ? return
? ? ? ? ? ? }
?? ? ? ? ? ?
? ? ? ? ? ? let sliderSafeArea = (self.distance);
?? ? ? ? ? ?
? ? ? ? ? ? scrollView.setContentOffset(CGPoint.init(x: 0, y: sliderSafeArea), animated: false)
?? ? ? ? ? ?
? ? ? ? }else if scrollView === containerScrollView{ //滑动scrollview
?? ? ? ? ? ?
? ? ? ? ? ? rootScrollView.isScrollEnabled = false
?? ? ? ? ? ?
? ? ? ? ? ? //滑动切换Tab
? ? ? ? ? ? let page = Double(scrollView.contentOffset.x/Screen_Width)
? ? ? ? ? ? self.sliderAnimationWithTag(tag: Int(page + 0.5))
?? ? ? ? ? ?
? ? ? ? }
? ? }
?? ?
? ? func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
? ? ? ? ? ? rootScrollView.isScrollEnabled = true
? ? }
?? ?
?? ?
}
?
extension JWDoubleScrollViewVC:UITableViewDelegate,UITableViewDataSource{
? ? func numberOfSections(in tableView: UITableView) -> Int {
? ? ? ? return 1
? ? }
?? ?
? ? func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
? ? ? ? return 50.0
? ? }
?? ?
? ? func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
? ? ? ? return 30
? ? }
?? ?
? ? func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
? ? ? ? let tableviewcell = tableView.dequeueReusableCell(withIdentifier: NSStringFromClass(UITableViewCell.classForCoder()), for: indexPath)
? ? ? ? tableviewcell.textLabel?.text = String.init(format: "第%i个", indexPath.row)
? ? ? ? tableviewcell.backgroundColor = .orange
? ? ? ? return tableviewcell
? ? }
?? ?
? ? func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
? ? ? ? tableView.deselectRow(at: indexPath, animated: false)
? ? }
?? ?
}
?
?
class MyScrollView:UIScrollView,UIGestureRecognizerDelegate{
?? ?
? ? //当前scrollview与其他scrollview都响应手势操作
? ? func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
? ? ? ? return true
? ? }
}
?
?
demo 地址:jwsource/JSDoubleScrollView
?
?
?
1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,会注明原创字样,如未注明都非原创,如有侵权请联系删除!;3.作者投稿可能会经我们编辑修改或补充;4.本站不提供任何储存功能只提供收集或者投稿人的网盘链接。 |
标签: #iOS #嵌套scrollview #屏幕宽度let #Screen_Width