irpas技术客

IOS嵌套scrollview滑动切换页面tab吸顶_hbysjw_ios scrollview嵌套scrollview

大大的周 5370

嵌套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