iOS开发------类似UI浏览器上方的滚动状态栏

6 篇文章 0 订阅

        前几天翻手机的时候,被UC浏览器的一个小细节吸引,就是上方的一个滚动栏,他的细节是什么,估计可以打开UC浏览器或者看完下面的描述会有所了解,刚开始会觉得很简单,但在即将结束的时候,还是感觉自己太天真了,具体的细节请看下面的模拟图

代码的GitHub:https://github.com/YRunIntoLove/YSimalilarScrollView



                           

                                                                                

    

        在真正介绍代码之前,我想先说一下思路,因为个人觉得,思路或者想法比代码重要的多,这个表现是应用了一个叫做视错觉的原理,就是让人的眼睛相信这是真的,实际却不是真的,具体的解释请百度一下视错觉就会出现很明确的解释,说一下具体的思路:


1、首先需要在底层铺上一个滚动视图(UIScrollView),记做bottomScrollView,相信这个肯定也都看得出来,毕竟滚动嘛

2、在滚动视图(bottomScrollView)上再铺上原始标签,也就是后面的显示Hello、Objective-C(- - Demo上写错了)的标签

3、需要创建一个用来标注选择的视图,记做showChooseView,也就是Demo中的那个红色的块状视图

4、核心的步骤,创建一个存放选中后标签的视图,也就是存放Demo中白色字体标签的视图,记做showSelectView.

5、将标签按照2中之前原始标签的frame依次铺到showSelectView

6、将创建好的showSelectView视图铺到showChooseView中,记得将showChooseView.clipsToBounds = true,为的是将5中视图超出showChooseView的部分隐藏不显示

7、为了响应点击事件,在1中的滚动视图上添加button,颜色设置为透明色,添加点击事件即可

8、在变化showChooseView的frame同时改变showSelectView的frame,让人感觉是颜色发生了变化,实际是是视图间进行了覆盖



原理明白之后,这个Demo就非常好做了。首先创建一个名字叫做YSimailarScrollView的类

设置了如下属性

//
//  YSimailarScrollView.swift
//  SimilarUCScrollDemo
//
//  Created by YueWen on 16/3/4.
//  Copyright © 2016年 YueWen. All rights reserved.
//

import UIKit

typealias ScrollBlock = (scale : Int) -> Void


/// 上端的滚动状态栏
class YSimailarScrollView: UIView {
    
    var bottomScrollView:UIScrollView!          //底层负责滚动的滚动视图
    var showChooseView:UIView!                  //负责显示选中的视图
    var showSelectView:UIView!                  //展示背后存放的视图
    
    var backTitleColor = UIColor.blackColor()   //底层展示文字颜色
    var showTitleColor = UIColor.whiteColor()   //选中展示文字颜色
    var showBackColor = UIColor.redColor()      //选中视图的背景色
    
    var fontSize = 16.0             //文字的大小
    var duration = 0.5              //动画完成的时间
    var numberOfTitle = 4           //每页呈现的个数
    var sHeight:CGFloat = 40.0      //状态栏的高度
    
    //数据变量
    var width : CGFloat?
    var labels : [UILabel]?
    var titles : [String] = ["Run","Into","Love","Yue"]
    
    var scrollBlockHandle:ScrollBlock?          //点击进行的回调


重写父类的init方法

    //MARK: - 重写父类的方法
    override init(frame: CGRect)
    {
        //初始化视图
        bottomScrollView = UIScrollView()
        showSelectView = UIView()
        showChooseView = UIView()
        
        //初始化数组
        labels = Array()
        width = frame.size.width / CGFloat(numberOfTitle)
        
        super.init(frame: frame)
    }

然后需要创建各个视图

1、bottomScrollView

    /**
     创建底层的滚动视图
     */
    func yBottomScrollView()
    {
        bottomScrollView.frame = self.bounds
        bottomScrollView.contentSize = CGSize(width: width! * CGFloat(titles.count),height: sHeight)
        bottomScrollView.showsHorizontalScrollIndicator = false
        self.addSubview(bottomScrollView)
    }

2、在bottomScrollView中铺上底层标签

    /**
     创建底层的标签
     */
    func createBottomLabel()
    {
        for(var i = 0; i < titles.count; i++)
        {
            let label = createLabel(i, titleColor: backTitleColor)
            bottomScrollView.addSubview(label)
        }
    }

3、创建标注视图showChooseView

    /**
     创建选中的视图
     */
    func yShowChooseView()
    {
        showChooseView.frame = frameOfView(0)
        showChooseView.backgroundColor = showBackColor
        showChooseView.clipsToBounds = true
        bottomScrollView.addSubview(showChooseView)
    }

4、创建showSelectView并将选中后显示的label铺到视图上

    /**
     创建展示背后存放的视图
     */
    func yShowSelectView()
    {
        showSelectView.frame = bottomScrollView.bounds
        
        for(var i = 0; i < titles.count; i++)
        {
            showSelectView.addSubview(createLabel(i, titleColor: showTitleColor))
        }
        
        showChooseView.addSubview(showSelectView)
    }

5、添加响应的按钮层

    /**
     创建响应的按钮
     */
    func createResponseButton()
    {
        for(var i = 0; i < titles.count; i++)
        {
            let button = createButton(i)
            bottomScrollView.addSubview(button)
        }
    }
    

6、下面是一些自定义的方法

6.1、便利创建标签的方法

    /**
     根据索引创建Label对象
     
     :param: index      索引
     :param: titleColor 显示的文字颜色
     
     :returns: 创建好的Label
     */
    func createLabel(index : NSInteger, titleColor : UIColor) -> UILabel
    {
        let frame = CGRectMake((CGFloat(index)) * width!, 0, width!, sHeight)
        let label = UILabel(frame: frame)
        label.textAlignment = NSTextAlignment.Center
        label.font = UIFont.systemFontOfSize(CGFloat(fontSize))
        label.textColor = titleColor
        label.text = titles[index]
        labels?.append(label)//添加到数组
        return label
    }

6.2.1、便利创建按钮的方法

    /**
     根据索引创建按钮对象
     
     :param: index 索引
     
     :returns: 当前标签的frame
     */
    func createButton(index: NSInteger) -> UIButton
    {
        let button = UIButton(type: UIButtonType.Custom)
        button.frame = frameOfView(index)
        button.tag = index
        button.backgroundColor = UIColor.clearColor()
        button.addTarget(self, action: Selector("labelDidTap:"), forControlEvents: UIControlEvents.TouchUpInside)
        return button
    }

6.2.2、响应方法

    /**
    按钮点击的目标动作回调
    
    :param: sender 回调的发送者
    */
    func labelDidTap(sender : AnyObject)
    {
        //获取button
        let button = sender as! UIButton

        //获取当前的frame
        let frame = frameOfView(button.tag)
        
        let frameSelect = handleFrame(frame)
        
        //回调Block
        scrollBlockHandle!(scale: Int(frame.origin.x / width!))
        
        //设置frame
        UIView.animateWithDuration(duration) { () -> Void in
            self.showChooseView.frame = frame
            self.showSelectView.frame =  frameSelect
        }
    }

6.3、设置闭包

    /**
    设置闭包回调
    
    :param: scrollBlockHandleNew 闭包回调
    */
    func selectTapBlockHandle(scrollBlockHandleNew:ScrollBlock)
    {
        scrollBlockHandle = scrollBlockHandleNew
    }

6.4、数据处理的方法

    /**
    处理当前的frame
    
    :param: frame 需要处理的frame
    
    :returns: 处理完毕的frame
    */
    func handleFrame(frame : CGRect) -> CGRect
    {
        var frameHandle = frame
        frameHandle.origin.x = -1 * frame.origin.x
        return frameHandle
    }
    
    
    //MARK: - 对外接口
    
    /**
    滚动到当前偏移量的位置
    
    :param: contentOff 滚动的偏移量
    */
    func sliderSimailarScrollView(contentOff : CGPoint)
    {
        //获取当前选中视图的位置
        var frame = showChooseView.frame
        
        //对点进行处理
        frame.origin.x = contentOff.x / CGFloat(numberOfTitle)
        
        //动画执行
        UIView.animateWithDuration(0.2) { () -> Void in
            
            self.showChooseView.frame = frame
            self.showSelectView.frame = self.handleFrame(frame)
        }
    }


来处理主要的ViewController.swift中的代码,没有太大的逻辑难度了,相信也都看得懂

//
//  ViewController.swift
//  SimilarUCScrollDemo
//
//  Created by YueWen on 16/3/4.
//  Copyright © 2016年 YueWen. All rights reserved.
//

import UIKit

class ViewController: UIViewController ,UIScrollViewDelegate{
    
    var scrollView = UIScrollView()
    var simailarScorllView:YSimailarScrollView!
    
    override func viewDidLoad() {
        
        super.viewDidLoad()
        
        let titles = ["Hello","Objctive-C","Swift","C++","Java"]
        
        //创建滚动视图对象
        let frame = CGRectMake(0, 30, self.view.bounds.size.width, 40)
        simailarScorllView = YSimailarScrollView(frame: frame)
        
        //设置相关属性
        simailarScorllView.titles = titles
        self.view.addSubview(simailarScorllView)
        
        simailarScorllView.selectTapBlockHandle { (scale) -> Void in
            
            //开始滚动下方的滚动视图
            self.scrollView.contentOffset = CGPoint(x: CGFloat(scale) * self.scrollView.bounds.size.width, y: 0)
            
        }
         
        //初始化滚动视图
        scrollView.frame = CGRectMake(0, 70, self.view.bounds.size.width, self.view.bounds.size.height - 70)
        scrollView.delegate = self;
        scrollView.pagingEnabled = true
        self.view.addSubview(scrollView)
        
        //初始化五个视图
        for(var i = 0; i < 5; i++)
        {
           scrollView.addSubview(createView(i, title: titles[i]))
        }
        
        scrollView.contentSize = CGSize(width: CGFloat(titles.count) * scrollView.bounds.size.width, height: scrollView.bounds.size.height)
        self.view.backgroundColor = UIColor.cyanColor()
        
    }
    
    
    func createView(index : Int,title : String) -> UIView
    {
        let view = UIView(frame: CGRectMake(CGFloat(index) * scrollView.bounds.size.width,0,scrollView.bounds.size.width,scrollView.bounds.size.height))
        
        let label = UILabel(frame: CGRectMake(10,20,150,30))
        label.textColor = UIColor.purpleColor()
        label.font = UIFont.systemFontOfSize(14)
        label.text = "我是" + title
        view.addSubview(label)
        
        return view
        
    }
    

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
    
    
    //MARK: - UIScrollView Delegate
    func scrollViewDidScroll(scrollView: UIScrollView)
    {
        //获取当前的偏移量
        let point = scrollView.contentOffset;
        
        simailarScorllView.sliderSimailarScrollView(point)
    }
    
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值