问题
i am trying to change the shape of UIBezierPath that i have created like in this tutorial: [https://www.appcoda.com/bezier-paths-introduction/] thats my code:
class Geometry: UIView {
//var path: UIBezierPath!
var path = UIBezierPath()
override func draw(_ rect: CGRect) {
createLine(x: 100, y: 100)
}
override init(frame: CGRect) {
super.init(frame: frame)
self.backgroundColor = UIColor.white
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
func transformShape(x:CGFloat, y:CGFloat)
{
path.removeAllPoints()
createLine(x: x, y: y)
}
func createLine(x: CGFloat, y: CGFloat)
{
var path = UIBezierPath()
path.move(to: CGPoint(x: 0.0, y: 0.0))
path.addLine(to: CGPoint(x: x, y: y))
path.close()
path.fill()
path.stroke()
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?)
{
let touch = touches.first
let location = (touch?.location(in: self))!;
transformShape(x:location.x, y:location.y)
}
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?)
{
let touch = touches.first
let location = (touch?.location(in: self))!;
transformShape(x:location.x, y:location.y)
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?)
{
let touch = touches.first
let location = (touch?.location(in: self))!;
transformShape(x:location.x, y:location.y)
}
}
i have added the the view in the viewcontroller like this:
import UIKit
var geo = Geometry()
let screenWidth: Int = 1024
let screenHeight: Int = 768
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
geo = Geometry(frame: CGRect(x: 0, y: 0, width: screenWidth, height: screenHeight))
self.view.addSubview(geo)
}
}
to make it easier to understand what i want to do i made this. i want to be able to move the end of both lines to the left and right on x without changing the y-postion
i have not found anything besides animation. but thats not what i want to accomplish. the top of the triangle should follow the movements of the finger. thanks
回答1:
It certainly isn't difficult to do this in a crude way:
Here's how I'm doing that:
class MyView : UIView {
override init(frame: CGRect) {
super.init(frame:frame)
backgroundColor = .yellow
let g = UIPanGestureRecognizer(target: self, action: #selector(pan))
self.addGestureRecognizer(g)
}
@objc
func pan(_ g:UIGestureRecognizer) {
switch g.state {
case .changed:
let p = g.location(in: self)
self.apex.x = p.x
self.setNeedsDisplay()
default: break
}
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
lazy var apex = CGPoint(x:self.bounds.midX, y:self.bounds.midY)
override func draw(_ rect: CGRect) {
let con = UIGraphicsGetCurrentContext()!
con.move(to: CGPoint(x: 0, y: self.bounds.maxY))
con.addLine(to: self.apex)
con.addLine(to: CGPoint(x: self.bounds.maxX, y: self.bounds.maxY))
con.strokePath()
}
}
In that code, I'm simply setting the apex point to where the finger is (keeping the y-component constant, as you specify), and redrawing the whole bezier path. So everything from there is just a question of refinement — reducing latency, for example (which you can do by anticipating touches).
来源:https://stackoverflow.com/questions/60778039/how-to-transform-uibezierpath-with-uitouch