【问题标题】:How to transform UIBezierPath with UITouch如何使用 UITouch 转换 UIBezierPath
【发布时间】:2020-03-20 16:28:36
【问题描述】:

我正在尝试更改我在本教程中创建的 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)
    }
}

我已经像这样在视图控制器中添加了视图:

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 上左右移动

除了动画,我没有找到任何东西。但这不是我想要完成的。三角形的顶部应该跟随手指的运动。谢谢

【问题讨论】:

  • 很简单:随着手指的移动,重新绘制路径,addLine(to: CGPoint(x: x, y: y)) 线变为手指现在所在的位置。
  • @matt 当我这样做时,我收到此错误:[未知进程名称] CGContextSetFillColorWithColor:无效上下文 0x0。如果要查看回溯,请设置 CG_CONTEXT_SHOW_BACKTRACE 环境变量。
  • 我很确定我应该在重新添加之前删除该行。但是我得到了同样的错误

标签: ios swift uibezierpath uitouch


【解决方案1】:

粗略地做到这一点当然不难:

我是这样做的:

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 分量不变),然后重新绘制整个贝塞尔路径。所以从那里开始的一切都只是一个细化的问题——例如减少延迟(你可以通过预测触摸来做到这一点)。

【讨论】:

  • 我明白我必须改变哪一点。但是我所做的应用程序会因以下错误而崩溃:[Unknown process name] CGContextSetFlatness: invalid context 0x0。如果要查看回溯,请设置 CG_CONTEXT_SHOW_BACKTRACE 环境变量。
  • 我还设置了全局变量并完全删除了路径并再次调用该函数:path.removeAllPoints() createLine(x: x, y: y)
  • 我看不到你在做什么;只有你可以看到你的代码。我试图给你一些关于如何做到这一点的想法;如何做到这一点并不有趣。显然,您正试图在 没有图形上下文时操作图形上下文。我在视图的draw(_:) 中做这一切,那里有一个图形上下文。
  • 是的,这正是我所说的。唯一可以合法调用createLine 的地方是draw(_:)。因此,当您这样做时它会起作用,而当您从所有其他地方调用它时则不起作用。顶点必须是createLine 可以从draw(_:) 中查看 的实例属性。
  • 对,不要复制我的代码,只是用它来展示你在自己的代码中需要的那种结构。
猜你喜欢
  • 2011-04-14
  • 1970-01-01
  • 1970-01-01
  • 2017-11-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多