CGContext рисует повернутые прямоугольники - PullRequest
1 голос
/ 14 марта 2019

Я пытаюсь нарисовать прямоугольники, которые разделены равными углами. Для этого я сначала рисую CGPath, а затем применяю преобразование к контексту. Я делаю это подряд 5 раз. Вот мой код и вывод. Как видите, вывод на скриншоте некорректный, прямоугольники искажаются, не знаю почему. Нужно знать, что я делаю не так. И я считаю, что я делаю излишнее, возможно, есть более простой способ добиться этого. Пожалуйста, укажите мне в правильном направлении.

  override func draw(_ rect: CGRect) {
    // Drawing code

    guard let context = UIGraphicsGetCurrentContext() else { return }

    context.setFillColor(UIColor.black.withAlphaComponent(0.35).cgColor)

    let pathWidth = CGFloat(40)
    let pathHeight = CGFloat(20)

    context.saveGState()

    let path = CGMutablePath()
    path.addRect(CGRect(x: rect.midX - pathWidth/2, y: rect.midY - pathHeight/2, width: pathWidth, height: pathHeight))
    context.addPath(path)
    context.drawPath(using: .fill)

    context.restoreGState()

    context.saveGState()
    let path2 = CGMutablePath()
    path2.addRect(CGRect(x: rect.midX - pathWidth/2, y: rect.midY - pathHeight/2, width: pathWidth, height: pathHeight))

    context.translateBy(x: 0, y: rect.height/2)
    context.rotate(by: -CGFloat.pi/20)
    context.translateBy(x: 0, y: -rect.height/2)
    context.addPath(path2)
    context.drawPath(using: .fill)
    context.restoreGState()

    context.saveGState()
    let path3 = CGMutablePath()
    path3.addRect(CGRect(x: rect.midX - pathWidth/2, y: rect.midY - pathHeight/2, width: pathWidth, height: pathHeight))

    context.translateBy(x: 0, y: rect.height/2)
    context.rotate(by: -2*CGFloat.pi/20)
    context.translateBy(x: 0, y: -rect.height/2)

    context.addPath(path3)
    context.drawPath(using: .fill)
    context.restoreGState()

    context.saveGState()
    let path4 = CGMutablePath()
    path4.addRect(CGRect(x: rect.midX - pathWidth/2, y: rect.midY - pathHeight/2, width: pathWidth, height: pathHeight))

    context.translateBy(x: 0, y: rect.height/2)
    context.rotate(by: -3*CGFloat.pi/20)
    context.translateBy(x: 0, y: -rect.height/2)

    context.addPath(path4)
    context.drawPath(using: .fill)
    context.restoreGState()

    context.saveGState()
    let path5 = CGMutablePath()
    path5.addRect(CGRect(x: rect.midX - pathWidth/2, y: rect.midY - pathHeight/2, width: pathWidth, height: pathHeight))

    context.translateBy(x: 0, y: rect.height/2)
    context.rotate(by: -4*CGFloat.pi/20)
    context.translateBy(x: 0, y: -rect.height/2)

    context.addPath(path5)
    context.drawPath(using: .fill)
    context.restoreGState()


    context.saveGState()
    let path6 = CGMutablePath()
    path4.addRect(CGRect(x: rect.midX - 10, y: rect.midY - 0.5, width: 20, height: 1))

    context.translateBy(x: 0, y: rect.height/2)
    context.rotate(by: -5*CGFloat.pi/20)
    context.translateBy(x: 0, y: -rect.height/2)

    context.addPath(path6)
    context.drawPath(using: .fill)
    context.restoreGState()

}

Это скриншот.

enter image description here

1 Ответ

0 голосов
/ 14 марта 2019

Вы можете попробовать следующий код, который не должен иметь перекос.

          var myLayer: CGLayer!
override func draw(_ rect: CGRect) {
    // Drawing code

    guard let context = UIGraphicsGetCurrentContext() else { return }

    context.setFillColor(UIColor.black.withAlphaComponent(0.35).cgColor)

    let pathWidth = CGFloat(40)
    let pathHeight = CGFloat(20)

     myLayer = CGLayer.init(context, size: CGSize.init(width: pathWidth, height: pathHeight), auxiliaryInfo: nil)
    let contex = myLayer.context
    let path = CGMutablePath()
    path.addRect(CGRect(x: 0, y: 0, width: pathWidth, height: pathHeight))
    contex?.addPath(path)
     contex?.setFillColor(UIColor.black.withAlphaComponent(0.35).cgColor)
    contex?.drawPath(using: .fill)


   (0...6).forEach
    {
   context.saveGState()

   context.translateBy(x: 0, y: rect.height/2)
   context.rotate(by: -CGFloat.pi * CGFloat($0) / 20)
   context.draw(myLayer!, at: CGPoint(x: rect.width / 2, y: -pathHeight / 2))

   context.restoreGState()
    }

более точный результат отображается следующим образом:

  (0...6).forEach
    {
   context.saveGState()

        let angle = CGFloat.pi * -CGFloat($0) / 20

        context.translateBy(x: 0, y: rect.height/2 + pathHeight/2 + (rect.width + pathWidth)/2 * sin (angle))
        context.translateBy(x: (rect.width + pathWidth)/2 * cos(angle)  , y: 0)

        context.rotate(by:angle)
        context.translateBy(x:  -pathWidth/2, y: -pathHeight / 2)

        context.draw(myLayer!, at: CGPoint.zero)



   context.restoreGState()
    }

}
...