Wednesday, November 11, 2026
HomeiOS Developmentios - CALayer drawing exterior of view

ios – CALayer drawing exterior of view

[ad_1]

I’ve this behaviour with this code:

import UIKit

class Web 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: .purple, fillColor: .init(grey: 0, alpha: 0.5), isPencil: true, connectsToStart: true, fillPencil: true)
    
    enum StandardPageSizes {
        case A4, LEGAL, LETTER
    }
    
    var firstCALayer = true
    var pointsTotal = 0
    
    override init(body: CGRect) {
        tremendous.init(body: .zero)
    }
    
    required init?(coder: NSCoder) {
        tremendous.init(coder: coder)
    }
    
    override func touchesBegan(_ touches: Set<UITouch>, with occasion: UIEvent?) {
        tremendous.touchesBegan(touches, with: occasion)
        guard let contact = touches.first else { return }
        let level = contact.location(in: self)
        firstPoint = level
        
        pointCounter = 1
        
        currentBezier = UIBezierPath()
        currentBezier.lineWidth = selectedPen.width
        selectedPen.getStroke().setStroke()
        currentBezier.transfer(to: level)
        
        previousPoint = level
    }
    
    override func touchesMoved(_ touches: Set<UITouch>, with occasion: UIEvent?) {
        tremendous.touchesMoved(touches, with: occasion)
        guard let contact = touches.first else { return }
        let level = contact.location(in: self)
        pointCounter += 1
        
        if (pointCounter == 3) {
            let midpoint = CGPoint(x: (morePreviousPoint.x + level.x)/2.0, y: (morePreviousPoint.y + level.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 = level
    }
    
    override func touchesEnded(_ touches: Set<UITouch>, with occasion: UIEvent?) {
        tremendous.touchesEnded(touches, with: occasion)
        guard let contact = touches.first else { return }
        let level = contact.location(in: self)
        
        if (pointCounter != 3) {
            if (selectedPen.connectsToStart) {
                currentBezier.addQuadCurve(to: firstPoint, controlPoint: previousPoint)
            } else {
                currentBezier.addQuadCurve(to: level, 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)
    }
    
    non-public func normPoint(level: CGPoint) -> CGPoint {
        return CGPoint(x: level.x/body.width, y: level.y/body.top)
    }
    
    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
        }
    }
    
}

Actually the one related components are touchesMoved and touchesEnded, the place CALayer’s are handled. As you’ll be able to see from the gif, I can draw exterior the bounds of the Web page (UIView) so long as I begin drawing contained in the bounds. I don’t want this – what I would really like is one thing the place you’ll be able to keep a stroke exterior of the bounds of the Web page (so long as you begin it on the Web page), however the stroke wont seem exterior of the Web page. Any concepts?

[ad_2]

RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Most Popular

Recent Comments