admin管理员组

文章数量:1401645

When I have

private lazy var aLine: RepairedCAShapeLayer {
    let v = RepairedCAShapeLayer()
    v.contentsScale = UIScreen.main.scale
    v.strokeColor = cfp.color.cgColor
    v.fillColor = nil
    v.lineWidth = 2
    v.lineJoin = .miter
    return v
}

I just realized that I inevitably ...

override func layoutSubviews() {
    super.layoutSubviews()
    aLine.path = fancyBezDrawing().cgPath

Where fancyBezDrawing() is a pile of code that creates a UIBezierPath.

I also just glanced in a few client code bases and the same. And innumerable examples of same on SO.

But I suppose, one could just

override func layoutSubviews() {
    super.layoutSubviews()
    aLine.path = fancyCGPDrawing()

Where, fancyCGPDrawing simply creates a ... CGPath.

Is there something I'm missing? Is there any reason one should make paths as UIBezierPath rather than just directly as CGPath, for layers??

When I have

private lazy var aLine: RepairedCAShapeLayer {
    let v = RepairedCAShapeLayer()
    v.contentsScale = UIScreen.main.scale
    v.strokeColor = cfp.color.cgColor
    v.fillColor = nil
    v.lineWidth = 2
    v.lineJoin = .miter
    return v
}

I just realized that I inevitably ...

override func layoutSubviews() {
    super.layoutSubviews()
    aLine.path = fancyBezDrawing().cgPath

Where fancyBezDrawing() is a pile of code that creates a UIBezierPath.

I also just glanced in a few client code bases and the same. And innumerable examples of same on SO.

But I suppose, one could just

override func layoutSubviews() {
    super.layoutSubviews()
    aLine.path = fancyCGPDrawing()

Where, fancyCGPDrawing simply creates a ... CGPath.

Is there something I'm missing? Is there any reason one should make paths as UIBezierPath rather than just directly as CGPath, for layers??

Share Improve this question asked Mar 24 at 18:19 FattieFattie 11.8k75 gold badges450 silver badges759 bronze badges Recognized by Mobile Development Collective 4
  • CGPath has features / methods which make some path construction much easier... but, since UIBezierPath exposes its .cgPath (and can be created from a cgpath) returning a CGPath or a UIBezierPath from a function is not a big deal. Generally speaking, as @stu said, in Swift there is very little difference in syntax. UIBezierPath has a little overhead, and is, therefore, (in theory) slightly slower - but it's rare that would be noticeable. – DonMag Commented Mar 25 at 17:45
  • You know what @DonMag we were indeed doing a rare thing with untold zillions of cached paths - and indeed it seems a bit faster to directly use CGPath! (ie never use UIBezierPath at all, UIBezierPath never seen in code.) It also to me seems more elegant to just use CGPath. indeed just as you say CGPath really has BETTER calls available, if anything. I guess I just in all these years didn't realize that UIBezPath was more of a convenience for objc use, as stu suggests. – Fattie Commented Mar 25 at 18:35
  • Which to use may also depend on ultimate use-case. If we're drawing directly, UIBezierPath has some advantages - for example, we can assign the .lineWidth / .lineCapStyle / .lineJoinStyle to the path object and call path.stroke() without needing to set those properties on the CGContext. As far as the "close the question" votes, they are flagging it as "Opinion Based" -- which would lead me to believe the voters misunderstood the question, or didn't realize that there are practical differences. – DonMag Commented Mar 25 at 20:04
  • true enough - you know I often just put a CGPath into a CAShapeLayer (indeed, as in the example I pasted in I just realized), and hence take care of end cap, color etc that way. (I find that's quite handy, if you want to change etc those values.) TY – Fattie Commented Mar 25 at 22:08
Add a comment  | 

1 Answer 1

Reset to default 1

I don't believe there's any major advantage in Swift to using UIBezierPath over a CGPath.
My assumption is that UIBezierPath exists to make creating a CGPath easier when writing Objective-C.
This is because the CGPath API is a C based API and is not very discoverable - for example to move a path to a point in Objective-C to a point you'd use this global function:

void CGPathMoveToPoint(CGMutablePathRef path, const CGAffineTransform *m, CGFloat x, CGFloat y)

Where as with UIBezierPath, all the available functions are instance methods, in this case:

- (void) moveToPoint:(CGPoint) point;

This doesn't matter in Swift because the CGPath/CGMutablePath APIs have been nicely adapted into structs and instance functions.

本文标签: