首先,您必须创建一个自定义的UIView,并且需要为您想要在UIView上进行转换的任何几何对象制作一个类,就像这样(仅适用于直线几何对象:线,折线,矩形)。
class GeoObj {
var path = UIBezierPath()
var points = [PointF]()
func createPath(){
points.removeAll()
points.append(PointF(0,0))
points.append(PointF(0,100))
path.move(to: points[0].cgPoint)
path.addLine(to: points[1].cgPoint)
}
}
(您的几何点)
struct PointF {
var x:Float = 0
var y:Float = 0
init(_ x:Float = 0, _ y:Float = 0) {
self.x = x
self.y = y
}
var cgPoint : CGPoint {
return CGPoint(x: CGFloat(self.x), y: CGFloat(self.y))
}
}
在UIView中,你必须有一些几何束(私有数组)来存储所有的几何模型,如下所示。每当你的自定义视图初始化时,你都会将业务数据注入到它里面,并渲染成Core Graphic对象。(在更高的层次上,当用户触摸某些东西时,你可以更新这些束并回调外部...)
private var geoModels = [GeoObj]() //you can create more
当UIView初始化时,您必须具备在图形上下文中呈现您的捆绑包的功能(将其放置在override func draw()中)
当您从UIViewController接收到移动(如dx,dy)时,运行该函数以移动您的对象
func moveObj(_ id : String,_ dx: Float,_ dy:Float){
for (i,obj) in geoModels.enumerated() {
if obj.id == id {
geoModels[i].points = translatePoints(points,dx,dy)
geoModels[i].path = remakePath(geoModels[i].points)
}
}
invalidate()
}
private func translatePoints(_ points : [PointF],_ dx:Float,_ dy:Float)->[PointF]{
var new_points = points
for (i,_) in new_points.enumerated(){
new_points[i].x += dx
new_points[i].y += dy
}
return new_points
}
private func remakePath(_ points:[PointF])->UIBezierPath{
let path = UIBezierPath()
path.move(to: points[0])
path.addLine(to: points[1])
return path
}
private func invalidate(){
self.setNeedsDisplay()
}
请记住,每次从UIView调用self.setNeedsDisplay()时,图形上下文都会清除其内容。
override func draw(_ rect: CGRect) {
print("draw")
super.draw(rect)
guard let ctx = UIGraphicsGetCurrentContext() else {
return
}
render(ctx)
}
不用担心延迟,我已经在我的真实项目中应用了这种方法,一切都运行得很顺畅。
let loc = ScreenCoordinates(x: 100, y: 100) setupCursor(location: loc) changeCursorLocation(location: CGPoint(x: 120, y: 100)) }
- Vince Gonzales