0%

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.
}
*/

}