我對這段代碼有這種行為:
import UIKit
class Page: UIView {
var bezierMemory = [BezierRecord]()
var currentBezier: UIBezierPath = UIBezierPath()
var firstPoint: CGPoint = CGPoint()
var previousPoint: CGPoint = CGPoint()
var morePreviousPoint: CGPoint = CGPoint()
var previousCALayer: CALayer = CALayer()
var pointCounter = 0
var selectedPen: Pen = Pen(width: 3.0, strokeOpacity: 1, strokeColor: .red, fillColor: .init(gray: 0, alpha: 0.5), isPencil: true, connectsToStart: true, fillPencil: true)
enum StandardPageSizes {
case A4, LEGAL, LETTER
}
var firstCALayer = true
var pointsTotal = 0
override init(frame: CGRect) {
super.init(frame: .zero)
}
required init?(coder: NSCoder) {
super.init(coder: coder)
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesBegan(touches, with: event)
guard let touch = touches.first else { return }
let point = touch.location(in: self)
firstPoint = point
pointCounter = 1
currentBezier = UIBezierPath()
currentBezier.lineWidth = selectedPen.width
selectedPen.getStroke().setStroke()
currentBezier.move(to: point)
previousPoint = point
}
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesMoved(touches, with: event)
guard let touch = touches.first else { return }
let point = touch.location(in: self)
pointCounter = 1
if (pointCounter == 3) {
let midpoint = CGPoint(x: (morePreviousPoint.x point.x)/2.0, y: (morePreviousPoint.y point.y)/2.0)
currentBezier.addQuadCurve(to: midpoint, controlPoint: morePreviousPoint)
let updatedCALayer = CAShapeLayer()
updatedCALayer.path = currentBezier.cgPath
updatedCALayer.lineWidth = selectedPen.width
updatedCALayer.opacity = selectedPen.strokeOpacity
updatedCALayer.strokeColor = selectedPen.getStroke().cgColor
updatedCALayer.fillColor = selectedPen.getFill()
if (firstCALayer) {
layer.addSublayer(updatedCALayer)
firstCALayer = false
} else {
layer.replaceSublayer(previousCALayer, with: updatedCALayer)
}
previousCALayer = updatedCALayer
pointCounter = 1
}
morePreviousPoint = previousPoint
previousPoint = point
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesEnded(touches, with: event)
guard let touch = touches.first else { return }
let point = touch.location(in: self)
if (pointCounter != 3) {
if (selectedPen.connectsToStart) {
currentBezier.addQuadCurve(to: firstPoint, controlPoint: previousPoint)
} else {
currentBezier.addQuadCurve(to: point, controlPoint: previousPoint)
}
let updatedCALayer = CAShapeLayer()
updatedCALayer.path = currentBezier.cgPath
updatedCALayer.lineWidth = selectedPen.width
updatedCALayer.opacity = selectedPen.strokeOpacity
updatedCALayer.strokeColor = selectedPen.getStroke().cgColor
updatedCALayer.fillColor = selectedPen.getFill()
if (firstCALayer) {
layer.addSublayer(updatedCALayer)
firstCALayer = false
} else {
// layer.setNeedsDisplay()
layer.replaceSublayer(previousCALayer, with: updatedCALayer)
}
}
firstCALayer = true
let bezierRecord = BezierRecord(bezier: currentBezier, strokeColor: selectedPen.getStroke(), fillColor: selectedPen.getFill(), strokeWidth: selectedPen.width)
bezierMemory.append(bezierRecord)
}
private func normPoint(point: CGPoint) -> CGPoint {
return CGPoint(x: point.x/frame.width, y: point.y/frame.height)
}
public class BezierRecord {
var bezier: UIBezierPath
var strokeColor: UIColor
var strokeWidth: CGFloat
var fillColor: CGColor
init(bezier: UIBezierPath, strokeColor: UIColor, fillColor: CGColor, strokeWidth: CGFloat) {
self.bezier = bezier
self.strokeColor = strokeColor
self.strokeWidth = strokeWidth
self.fillColor = fillColor
}
}
}
實際上,唯一相關的部分是 touchesMoved 和 touchesEnded,其中 CALayer 被處理。從 gif 中可以看出,只要我開始在邊界內繪制,我就可以在頁面 (UIView) 的邊界之外進行繪制。我不想要這個 - 我想要的是你可以在頁面邊界之外保持筆畫(只要你在頁面上開始它),但筆畫不會出現在頁面之外。有任何想法嗎?
編輯:我應該補充一點,對于這些 UIBezierCurves,(0, 0) 被認為是頁面的左上角(白色),而不是整個視圖。因此,例如,從頁面開始并繼續的貝塞爾曲線是負數。
uj5u.com熱心網友回復:
您需要做的就是.clipsToBounds = true在視圖上進行設定。
一種方法:
override init(frame: CGRect) {
super.init(frame: .zero)
commonInit()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
commonInit()
}
func commonInit() {
self.clipsToBounds = true
}
你可以把這self.clipsToBounds = true兩個函式都放進去init,但通常的做法(不是雙關語)添加一個像這樣的“通用初始化”函式(它可以命名為任何名字......這就是我的做法)。我們經常有其他我們想要呼叫的“初始設定”代碼,這樣可以避免重復代碼。
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/491667.html
下一篇:單擊按鈕后如何使輸入欄位為空?
