1

I am try draw shape using UIBezietPath but each time I am have trouble with "Curve". For solving my problem I did use Paint Code, code was be generated well, but it is a static shape , and I try translate this code for dynamic screen size, but each time I have trouble with half of shape.

Can anyone help me translate this code correctly?

Generated code by Paint Code:

//// Color Declarations
let fillColor = NSColor(red: 0.118, green: 0.118, blue: 0.149, alpha: 1)

//// Bezier Drawing
let bezierPath = NSBezierPath()
bezierPath.move(to: NSPoint(x: 8.83, y: 89))
bezierPath.line(to: NSPoint(x: 154.29, y: 89))
bezierPath.curve(to: NSPoint(x: 163.01, y: 81.04), controlPoint1: NSPoint(x: 158.71, y: 89), controlPoint2: NSPoint(x: 162.21, y: 85.39))
bezierPath.curve(to: NSPoint(x: 206.45, y: 45.05), controlPoint1: NSPoint(x: 166.77, y: 60.57), controlPoint2: NSPoint(x: 184.79, y: 45.05))
bezierPath.curve(to: NSPoint(x: 249.89, y: 81.04), controlPoint1: NSPoint(x: 228.11, y: 45.05), controlPoint2: NSPoint(x: 246.12, y: 60.57))
bezierPath.curve(to: NSPoint(x: 258.61, y: 89), controlPoint1: NSPoint(x: 250.68, y: 85.39), controlPoint2: NSPoint(x: 254.19, y: 89))
bezierPath.line(to: NSPoint(x: 405.17, y: 89))
bezierPath.curve(to: NSPoint(x: 414, y: 80.21), controlPoint1: NSPoint(x: 410.05, y: 89), controlPoint2: NSPoint(x: 414, y: 85.06))
bezierPath.line(to: NSPoint(x: 414, y: 8.79))
bezierPath.curve(to: NSPoint(x: 405.17, y: 0), controlPoint1: NSPoint(x: 414, y: 3.94), controlPoint2: NSPoint(x: 410.05, y: 0))
bezierPath.line(to: NSPoint(x: 8.83, y: 0))
bezierPath.curve(to: NSPoint(x: 0, y: 8.79), controlPoint1: NSPoint(x: 3.95, y: 0), controlPoint2: NSPoint(x: 0, y: 3.94))
bezierPath.line(to: NSPoint(x: 0, y: 80.21))
bezierPath.curve(to: NSPoint(x: 8.83, y: 89), controlPoint1: NSPoint(x: 0, y: 85.06), controlPoint2: NSPoint(x: 3.95, y: 89))
bezierPath.close()
fillColor.setFill()
bezierPath.fill()

Shape: enter image description here

Ice
  • 680
  • 1
  • 10
  • 23

1 Answers1

1

First extend CGPoint and create a scaled(by:) method:

extension CGPoint {
    func scaled(by value: CGFloat) -> CGPoint { applying(.init(scaleX: value, y: value)) }
}

Then get the actual superview's bounds width and divide by the width of your path 414.

let value: CGFloat = superview!.bounds.size.width / 414

Now you just need to apply the scale value to every point of your path:

bezierPath.move(to: NSPoint(x: 8.83, y: 89).scaled(by: value))
Leo Dabus
  • 229,809
  • 59
  • 489
  • 571
  • Great answer! This code work cool, I am tested this on all iPhone & iPad, work well. But on iPad this bottom menu seems slightly big, what need change for iPad devices? I understand your code but not understood why you divide screed width on 414? For iPad Devices this value need change? Are you divide on 414 because max x position 414 I am right? – Ice Nov 30 '20 at 10:12
  • 414 is the highest x value in your path (screen width). Regarding your issue with the iPad I am not sure but you will need to debug and find out a percentage value to multiply the scale you are using now. – Leo Dabus Nov 30 '20 at 13:48
  • This is a nice extension, but he's only scale width to his frame, I wand to fit my shape also to his height, do you have a solution? – Mickael Belhassen Oct 19 '22 at 13:26
  • @MickaelBelhassen Not sure what you mean by "only scale width". It scales both width and height proportionally. – Leo Dabus Oct 19 '22 at 15:33
  • @MickaelBelhassen If you are talking about the scale used you just need to calculate both width and height and create an extension similar to the one I have posted with valueX for scaleX and valueY for scaleY. – Leo Dabus Oct 19 '22 at 15:37
  • @LeoDabus Right your extension scale the height proportionally. I would like that the shape fill the frame without keeping proportion. – Mickael Belhassen Oct 20 '22 at 06:51
  • I did not understand how to do it, can you add code snippet – Mickael Belhassen Oct 20 '22 at 06:57