二、代码分析
这个控件本质就是从UIView继承的一个类而已。所以整个代码其实就是一个定制的UIView类。
根据UIView的规则进行如下初始化:
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
override init(frame: CGRect) {
self.pointer = UIImageView(image: UIImage(named:"pointer2.png"))
self.gaugeView = UIImage(named: "gaugeback.png")
self.frameCurr = frame
self.gv = GaugeParam(frame: frame)
super.init(frame: frame)
self.setFrameInit(frame)
}
构造函数没啥好说的,解释一下required init,如果继承了init(),就必须实现Required Initializers。
为了初始化类的参数设计了一个结构
struct GaugeParam{
var maxNum: Float = MAXVALUE
var minNum: Float = 0.00
var maxAngle: Float = MAXOFFSETANGLE
var minAngle: Float = -MAXOFFSETANGLE
var gaugeValue: Float = 0.00
var gaugeAngle: Float = -MAXOFFSETANGLE
var frame: CGRect
var angleperValue: Float{
get{
return (self.maxAngle - self.minAngle)/(self.maxNum- self.minNum)
}
}
var scaleNum: Float{
get{
return (Float(DEFLUATSIZE)/Float(self.frame.size.width))
}
}
init(frame:CGRect){
self.frame = frame
}
}
上面这个结构体挺简单的,没啥好解释的。
下面是重头戏了,GaugePanel是主类,所有操作都是在其中完成的。
代码结构如下:
个别算法解释一下(老鸟请绕行):
func parseToX(radius: CGFloat,angle: CGFloat) -> CGFloat{
let temp = self.transToRadian(angle)
return radius*cos(temp)
}
初中平面几何的知识,知道半径和角度求X和Y坐标。
对pointToAngle(duration: CGFloat,angle: CGFloat)中的代码进行一下解释:
CATransform3DRotate(CATransform3DIdentity,self.transToRadian(CGFloat(gv.gaugeAngle) + distance*CGFloat(i)), 0, 0, 1)
这个是产生一个3D旋转,因为是平面旋转所以是围绕Z轴进行的,最后一个参数设置为1,self.transToRadian(CGFloat(gv.gaugeAngle)+ distance*CGFloat(i))是计算出一系列的角度。
values.addObject(NSValue(CATransform3D:v)),其实CATransform3DRotate并不会立即产生旋转,而是添加到一个NSMutableArray数组中,NSMutableArray的元素不是AnyObject,需要用NSValue函数包装一下,真正发生旋转是在pointer.layer.addAnimation(ani,forKey: "any")进行的,ani包含了Values的内容。
override func drawRect(rect: CGRect)这个函数并没有显式的调用,是在containView.addSubview(panel)的时候被自动触发的。
好了,我要休息了,希望这偏文章给swift的初学者(其实大家都是初学者,老鸟也就是几个月的经验)有所帮助。对这个控件的谬误之处和改进意见可以和我联系.QQ:脐林 32819362。