【问题标题】:Mirrored and alternating output strokes in CALayer contextCALayer 上下文中的镜像和交替输出笔画
【发布时间】:2017-06-20 19:28:58
【问题描述】:

我正在为我的 iPad 开发 Apple Pencil 应用程序,并希望在子图层中捕捉铅笔笔画。每次铅笔移动时,我都会在子图层中添加一个笔触,然后保存图像。对于下一个笔画,我绘制保存的图像,添加下一个笔画,然后再次保存。出于某种原因,每隔一个笔画就会与前一个笔画相反,因此看起来虚线图像在框架的水平中心以镜像形式显示。我知道我可以通过其他方式完成同样的事情,但我真的很想知道为什么会这样——显然我不明白关于使用层和 CGContext 的一些事情。下面是重现问题的最小代码集。请注意,这不是我的实际代码(我使用视图和图层等),但我将所有内容都整合到一个 VC 中,以便在单视图应用程序中轻松重新创建:

import UIKit

var touch: UITouch!
var loc: CGPoint!
var prevLoc: CGPoint!

var lineWidth: CGFloat = 3
var drawColor: UIColor = UIColor.black

var myView: UIView!
var pLay: CALayer!
var img: CGImage!

class ViewController: UIViewController, CALayerDelegate {

override func viewDidLoad() {
    super.viewDidLoad()
    myView = self.view!
    pLay = CALayer()
    pLay.frame = myView.bounds
    pLay.bounds = pLay.frame
    pLay.delegate = self
    myView.layer.addSublayer(pLay)
    pLay.setNeedsDisplay()
}

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    guard let touch = touches.first else { return }
    let start = touch.location(in: myView)
    print("START: X: \(start.x) Y: \(start.y)")
}

override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
    guard let touch = touches.first else { return }
    let end = touch.location(in: myView)
    print("END: X: \(end.x) Y: \(end.y)")
    pLay.setNeedsDisplay()
}

override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
    touch = touches.first
    prevLoc = touch.previousLocation(in: myView)
    loc = touch.location(in: myView)
    if ((loc.x != prevLoc.x) && (loc.y != prevLoc.y)) {
        print("MOVED: prev: \(prevLoc.x), \(prevLoc.y) loc: \(loc.x), \(loc.y)")
        pLay.setNeedsDisplay()
    }
}

func draw(_ layer: CALayer, in con: CGContext) {
    guard let t = touch else {
        return
    }

    if (img != nil) {
        con.draw(img, in: layer.bounds)
    }

    if t.type == .stylus {
        lineWidth = 2
        con.setStrokeColor(drawColor.cgColor)
    }

    con.setLineWidth(lineWidth)
    con.setLineCap(.round)

    con.move(to: CGPoint(x: prevLoc.x, y: prevLoc.y))
    con.addLine(to: CGPoint(x: loc.x, y: loc.y))
    con.strokePath()
    img = con.makeImage()
}

}

【问题讨论】:

    标签: ios swift xcode ipad


    【解决方案1】:

    这是一个“如果它没有坏就不要修复它”的案例。我使用 ImageView 让这段代码运行良好,但觉得它效率低下,因此尝试在图层中实现。我试图保存状态然后在图层中恢复的方式基本上是不合适的。这里的主要问题是在创建镜像绘图的draw 中调用con.draw(img, in: layer.bounds),但是还有足够多的其他问题(例如不同的坐标原点)让我回到原来的实现。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-14
      相关资源
      最近更新 更多