如何使用 UITouch 转换 UIBezierPath
How to transform UIBezierPath with UITouch
我正在尝试更改我在本教程中创建的 UIBezierPath 的形状:
[https://www.appcoda.com/bezier-paths-introduction/]
那是我的代码:
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)
}
}
我已经在 viewcontroller 中添加了这样的视图:
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)
}
}
为了让大家更容易理解我想做什么,我做了这个。我希望能够在不更改 y 位置的情况下将两条线的末尾在 x 上向左和向右移动
除了动画我还没有找到任何东西。但这不是我想要完成的。三角形的顶部应该跟随手指的移动。谢谢
粗暴地做到这一点当然不难:
我是这样做的:
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()
}
}
在该代码中,我只是将顶点设置为手指所在的位置(保持 y 分量不变,如您指定的那样),然后重新绘制整个贝塞尔曲线路径。因此,一切都只是一个改进的问题——例如,减少延迟(您可以通过预期触摸来做到这一点)。
我正在尝试更改我在本教程中创建的 UIBezierPath 的形状: [https://www.appcoda.com/bezier-paths-introduction/] 那是我的代码:
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)
}
}
我已经在 viewcontroller 中添加了这样的视图:
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)
}
}
为了让大家更容易理解我想做什么,我做了这个。我希望能够在不更改 y 位置的情况下将两条线的末尾在 x 上向左和向右移动
除了动画我还没有找到任何东西。但这不是我想要完成的。三角形的顶部应该跟随手指的移动。谢谢
粗暴地做到这一点当然不难:
我是这样做的:
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()
}
}
在该代码中,我只是将顶点设置为手指所在的位置(保持 y 分量不变,如您指定的那样),然后重新绘制整个贝塞尔曲线路径。因此,一切都只是一个改进的问题——例如,减少延迟(您可以通过预期触摸来做到这一点)。