本文阅读时长
30
分钟,主要介绍PaintCode
在iOS
开发中的使用,利用PaintCode
绘制简单的矢量图形,并生成相应的iOS
代码,利用生成的图形代码引用到相应的工程中实现动画效果。
PaintCode的介绍
PaintCode
是Mac
端很好用的一款矢量绘图软件,相较于Sketch
不同的是可以生成基于Core Graphics
的Objective-C
或Swift
的图形代码,使用起来非常方便,软件是收费的,有钱的话可以支持正版!
时钟主体绘制
打开软件后如下图所示:
右边的
Canvas
是属性检查器,用于调整画布的属性。将canvas
命名为Stopwatch
,将宽度和高度设为250
,将Code Export
设置为StyleKit Drawing& Image Method
。画布左上角是主原点,所有图形的位置都是从这个像素点计算而来。
在工具条的上方选择Oval
。
在画布上画一个圆,并在右边的属性检查器上设置
Oval
的宽和高都为220
,x
和y
方向的坐标为15
和30
。在右边的
Fill
选项中点击箭头选择Add new Color
,并将新颜色的取名为Base Color
并修改十六进制的值为#118DDA
。接着选择
Rect
矩形,绘制矩形并设置属性为:
- X:114
- Y:2
- W:22
-
H:34
再次如下图拖拽二个矩形,并设置大矩形的宽高为30
和20
,小矩形的宽高都为20
,位置先暂时拖到合适的位置,然后选中大矩形,在右侧属性面板中选中Transforms
后设置Rotation
为-45
进行旋转操作。
拖拽小的正方形到合适的位置,并选择工具条上方的Union
合并按钮进行合并,并设置合并后的x
和y
坐标值为200
和25
。
完成后如下图所示,按住Command-S
保存为PaintCodeTest
。
时钟指针绘制
选中Stopwatch
画布,然后在画布之外的空白地方右键会出现Add New Canvas
,选中默认的(250×250) Size of Stopwatch
创建一个尺寸大小与Stopwatch
相同的画布,将新画布命名为Stopwatch_Hand
并将高度设为220
,选择Drawing Method
模式并调整背景颜色为黑色。
回到
Stopwatch
画布,绘制一个白色圆,其半径为30
,并拖拽到时钟表盘的中心(Paintcode
会有对齐指示,对齐后白色小圆的坐标值为(110,125)
),绘制一个白色长条矩形,其宽和高分别为8
和115
,并拖拽到合适位置。在合并之前需要调整合并后的中心点以便指针可以绕着表盘的中心进行旋转,按住
Shift
选中白色小圆形和白色长条矩形,并在右侧属性面板下展开Transforns
使得二者的相对原点可见。只选中白色小圆,用鼠标拖动绿色相对原点到表盘中心,可以看到
Transforms
下的Offset
都为-15
,同时白色小圆的坐标值为(125,140)
。同时选中白色小圆和长条矩形执行合并操作,可以看到相对原点在左上方。
拖动绿色的相对原点直到更改合并后的坐标值为上一步小圆点的坐标值也即
(125,140)
,这里不要用手动输入。选中合并后的指针按住
Command-X
然后Command-V
到Stopwatch_Hand
上,由于Stopwatch_Hand
画布的高为220
比Stopwatch
的250
小了30
,所以调整Stopwatch_Hand
指针的坐标值为(125,110)
。点击左边栏的
Variables
选择Angle
添加变量,并将起始角度值设为0
度。按住
Crtl
键点击变量右侧的空心圆圈拖动到Stopwatch_Hand
画布右侧属性面板下Transforms
下的Rotation
处。导出为StyleKit
选择StyleKit
标签会展示Colors
,Gradients
, Shadows
,Images
, 和 Drawing Methods
以供导出!
点击
Add Color
选择Base Color
添加颜色到StyleKit Colors
中以便导出代码后能修改图形的颜色。修改右侧
StyleKit
相关的信息后点击硕大的Export
导出按钮即可得到相应图形的swift
文件。PaintCodeTest.swif
t中的自动生成的部分图形代码如下所示:
@objc dynamic public class func drawStopwatch(frame targetFrame: CGRect = CGRect(x: 0, y: 0, width: 250, height: 250), resizing: ResizingBehavior = .aspectFit) {
//// General Declarations
let context = UIGraphicsGetCurrentContext()!
//// Resize to Target Frame
context.saveGState()
let resizedFrame: CGRect = resizing.apply(rect: CGRect(x: 0, y: 0, width: 250, height: 250), target: targetFrame)
context.translateBy(x: resizedFrame.minX, y: resizedFrame.minY)
context.scaleBy(x: resizedFrame.width / 250, y: resizedFrame.height / 250)
//// Oval Drawing
let ovalPath = UIBezierPath(ovalIn: CGRect(x: 15, y: 30, width: 220, height: 220))
PaintCodeTest1.color.setFill()
ovalPath.fill()
//// Rectangle Drawing
let rectanglePath = UIBezierPath(rect: CGRect(x: 114, y: 2, width: 22, height: 34))
PaintCodeTest1.color.setFill()
rectanglePath.fill()
//// Bezier Drawing
let bezierPath = UIBezierPath()
bezierPath.move(to: CGPoint(x: 214.14, y: 25))
bezierPath.addLine(to: CGPoint(x: 235.36, y: 46.21))
bezierPath.addLine(to: CGPoint(x: 221.21, y: 60.35))
bezierPath.addCurve(to: CGPoint(x: 218.21, y: 57.35), controlPoint1: CGPoint(x: 221.21, y: 60.35), controlPoint2: CGPoint(x: 220.03, y: 59.17))
bezierPath.addLine(to: CGPoint(x: 203, y: 57.35))
bezierPath.addCurve(to: CGPoint(x: 203, y: 42.14), controlPoint1: CGPoint(x: 203, y: 57.35), controlPoint2: CGPoint(x: 203, y: 48.06))
bezierPath.addCurve(to: CGPoint(x: 200, y: 39.14), controlPoint1: CGPoint(x: 201.19, y: 40.33), controlPoint2: CGPoint(x: 200, y: 39.14))
bezierPath.addLine(to: CGPoint(x: 214.14, y: 25))
bezierPath.close()
PaintCodeTest1.color.setFill()
bezierPath.fill()
context.restoreGState()
}
引入图形文件到Xcode
直接将生成的PaintCodeTest.swift
文件引入到工程中,并新建名为Stopwatch.swift
和StopwatchHand.swift
的文件,在二个文件中分别添加如下代码:
Stopwatch.swift:
import UIKit
import Foundation
@IBDesignable
class Stopwatch: UIView {
override func draw(_ rect: CGRect) {
PaintCodeTest1.drawStopwatch()
}
}
StopwatchHand.swift:
import UIKit
import Foundation
@IBDesignable
class StopwatchHand: UIView {
private var _angle:CGFloat = 0.0;
override func draw(_ rect: CGRect) {
PaintCodeTest1.drawStopwatch_Hand(frame: CGRect(x: 0, y: 0, width: bounds.size.width, height: bounds.size.height), resizing: .aspectFit, angle: angleHand)
}
var angleHand:CGFloat {
set (newAngleHand) {
_angle = newAngleHand
setNeedsDisplay()
}
get {
return _angle
}
}
}
打开Main.storyboard
快速添加个一个UIView
并设置相关约束如下:
- Width Equals:250
- Height Equals:250
- Align Center X to:Superview
- Top Space to:Top Layout Guide
关联此UIView
到Stopwatch
上,因为类声明为了@IBDesignable
所以此时可以适时的预览。
同样的方法添加一个
UIView
到Stopwatch
的上面,设置二者约束为大小位置都相等,设置background color
为clear color
并关联到StopwatchHand
。在ViewController
中利用定时器使时钟走起来。
import UIKit
class ViewController: UIViewController {
@IBOutlet var stopWatchHandView: StopwatchHand!
private var myTime:Timer?;
override func viewDidLoad() {
super.viewDidLoad()
stopWatchHandView.angleHand = 0.0;
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
rotateStopWatchHand()
}
func rotateStopWatchHand() {
myTime = Timer(timeInterval: 1, repeats: true, block: { [weak self](Timer) in
self?.stopWatchHandView.angleHand = (self?.stopWatchHandView.angleHand)! - 6;
if ((self?.stopWatchHandView.angleHand)! < -360){
self?.stopWatchHandView.angleHand = 0;
}
})
RunLoop.current.add(myTime!, forMode: .common)
myTime?.fire()
}
}
总结
利用Paintcode
生成的图形代码可以大大的提高实际开发的效率,无需为复杂的图形绘制花费太多的时间,同时利用Paintcode
的变量能很方便的做出复杂的动画,达到事半功倍的效果,且Paintcode
使用起来非常简单,同时还支持Sketch
的导入,本文在此不做过多的介绍。
网友评论