iOS开发:swift自定义动画tab控件

控件效果如下图:
ios-swift-tab
切换时会有动画效果。
原理,使用贝塞尔曲线做动画,参考 iOS开发:仿余额宝金额跳动效果
代码如下:

UICTabView.swift:

import UIKit

@IBDesignable class UICTabView: UIView {

     var delegate:UICTabViewDelegate?
    //标记动画结束,没结束不响应事件
    var animationFinish = true
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }
    override init(frame: CGRect) {
        super.init(frame: frame)
    }
    //tab数量
    @IBInspectable var tabCount:Int = 3 {
        didSet {
            setNeedsDisplay()
            
        }
    }
    ///字体大小
    @IBInspectable var tabFontSize:CGFloat = 15 {
        didSet {
            setNeedsDisplay()
        }
    }
    ///tab文本颜色 
    @IBInspectable var textColor:UIColor = UIColor.whiteColor() {
        didSet {
            setNeedsDisplay()
        }
    }
    ///指示条的高度
    @IBInspectable var indicatorHeight:CGFloat = 10 {
        didSet {
             setNeedsDisplay()
        }
    }
    
    ///选中项
    @IBInspectable var selectedIndex:Int = 0 {
        didSet {
            if (selectedIndex > tabCount - 1) {
                selectedIndex = tabCount - 1
            }
            indicatorViewContainer?.selectedIndex = selectedIndex
        }
        
    }
    //tab上显示的文字
    var tabTexts:[String] = []
    
    var tabWidth:CGFloat = 0
    //指示器container
    var indicatorViewContainer:UICTabIndicatorViewContainer!
    override func drawRect(rect: CGRect) {
        for view in self.subviews {
            view.removeFromSuperview()
        }
        
        let width = self.frame.size.width
        let height = self.frame.size.height
        tabWidth = width / CGFloat(tabCount)
        
        
        for i in 0..= pointNumber) {
               indicator?.frame.origin.x = tabWidth * CGFloat(selectedIndex)
                (self.superview as! UICTabView).animationFinish = true
            }else{
                let currentPoint: NSArray = allPoints.objectAtIndex(indexCurrent) as! NSArray
                let value = currentPoint.objectAtIndex(1) as! Float
                let currentTime = currentPoint.objectAtIndex(0) as! Float
                
                ++indexCurrent
                lastTime = currentTime;
                
                
                indicator?.frame.origin.x = CGFloat(value)
                //延迟调用changeNumberBySelector方法,重新设string
                let delay = durationPerFrame * Double(NSEC_PER_MSEC)
                let time = dispatch_time(DISPATCH_TIME_NOW, Int64(delay))
                //循环调用自己
                dispatch_after(time, dispatch_get_main_queue(), {
                    NSThread.detachNewThreadSelector(Selector("smoothMove"), toTarget:self, withObject: nil)
                })
                
            }
        }
        
    }

}

//MARK: 委托协议
///tab切换事件
@objc protocol UICTabViewDelegate {
    ///tab点击
    optional func tabView(tabView:UICTabView,selectedTabIndex:Int)
}

可在storyboard中设置tab数量,指示器颜色等,但tab内容需要在代码里设
ViewController中使用:

import UIKit

class HomeViewController: UIViewController,UICTabViewDelegate {

    @IBOutlet weak var headerView: UIView!
    
    @IBOutlet weak var tabView: UICTabView!
    
    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
        //定义渐变的颜色,多色渐变太魔性了,我们就用两种颜色
        let topColor = UIColor(red: (206/255.0), green: (53/255.0), blue: (33/255.0), alpha: 1)
        let buttomColor = UIColor(red: (215/255.0), green: (75/255.0), blue: (58/255.0), alpha: 1)
        //将颜色和颜色的位置定义在数组内
        let gradientColors: [CGColor] = [topColor.CGColor, buttomColor.CGColor]
        let gradientLocations: [CGFloat] = [0.0, 1.0]
        setGradientBackground(self.headerView, gradientColors: gradientColors, gradientLocations: gradientLocations)
        
        tabView.delegate = self

        
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
    
    
    func tabView(tabView:UICTabView,selectedTabIndex:Int) {
        //tab切换
        PLog.d("切到\(selectedTabIndex)")
    }
    
    override func preferredStatusBarStyle() -> UIStatusBarStyle {
        return UIStatusBarStyle.LightContent
    }

    /*
    // MARK: - Navigation

    // In a storyboard-based application, you will often want to do a little preparation before navigation
    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        // Get the new view controller using segue.destinationViewController.
        // Pass the selected object to the new view controller.
    }
    */

}

© 2016, 冰冻鱼. 请尊重作者劳动成果,复制转载保留本站链接! 应用开发笔记