CAShapeLayer не отображается должным образом

#swift #uikit #calayer #cashapelayer

#swift #uikit #calayer #cashapelayer

Вопрос:

У меня есть представление, в котором есть некоторые CAShapeLayer буквы s. Я лениво создаю его следующим образом:

 lazy var myViewWithLayersOnIt: UIView = {
    let view = UIView(frame: CGRect(origin: CGPoint(x: 14,
                                                    y: 2),
                                    size: CGSize(width: 10,
                                                 height: 10)))
    view.translatesAutoresizingMaskIntoConstraints = false

    let outerCircleLayer = CAShapeLayer()
    let outerPath = UIBezierPath(ovalIn: view.frame).cgPath
    outerCircleLayer.path = outerPath
    outerCircleLayer.position = view.center
    outerCircleLayer.fillColor = UIColor.white.cgColor
    view.layer.addSublayer(outerCircleLayer)

    let innerFrame = CGRect(origin: CGPoint(x: 1.5,
                                            y: 1.5),
                            size: CGSize(width: 8.5,
                                         height: 8.5))
    let innerCircleLayer = CAShapeLayer()
    let innerPath = UIBezierPath(ovalIn: innerFrame).cgPath
    innerCircleLayer.path = innerPath
    innerCircleLayer.position = view.center
    innerCircleLayer.fillColor = UIColor.red.cgColor
    view.layer.addSublayer(innerCircleLayer)

    return view
}()
  

В то время как все, что должно отображаться на экране, отображается, CAShapeLayer буквы s не находятся в центре view . Я подумал, что это может быть связано с ленивым созданием экземпляра, поэтому я отказался от lazy и вижу точно такую же проблему. Что я забыл сделать?

Вот как это происходит:

введите описание изображения здесь

Спасибо за чтение. Я приветствую ваш вклад.

Комментарии:

1. Никогда не правильно говорить такие вещи, как innerCircleLayer.position = view.center , кстати. view.center не является центром view . Скорее, это то, где view находится .

Ответ №1:

Вы должны использовать view.bounds вместо view.frame for outerPath . Нет необходимости устанавливать значение position of outerCircleLayer , nor innerCircleLayer .

 lazy var myViewWithLayersOnIt: UIView = {
    let view = UIView(frame: CGRect(origin: CGPoint(x: 14,
                                                        y: 2),
                                        size: CGSize(width: 10,
                                                     height: 10)))
        

    view.translatesAutoresizingMaskIntoConstraints = false
    view.backgroundColor = UIColor.black

    let outerCircleLayer = CAShapeLayer()
    let outerPath = UIBezierPath(ovalIn: view.bounds).cgPath /// bounds!
    outerCircleLayer.path = outerPath
//    outerCircleLayer.position = view.center
    outerCircleLayer.fillColor = UIColor.white.cgColor
    view.layer.addSublayer(outerCircleLayer)

    let innerFrame = CGRect(origin: CGPoint(x: 1.5,
                                                y: 1.5),
                                size: CGSize(width: 8.5,
                                             height: 8.5))
    let innerCircleLayer = CAShapeLayer()
    let innerPath = UIBezierPath(ovalIn: innerFrame).cgPath
    innerCircleLayer.path = innerPath
//    innerCircleLayer.position = view.center
    innerCircleLayer.fillColor = UIColor.red.cgColor
    view.layer.addSublayer(innerCircleLayer)

    return view
}()

  

Результат:

круги с центром внутри друг друга

Красный круг смещен от центра, потому что

 let innerFrame = CGRect(origin: CGPoint(x: 1.5,
                                        y: 1.5),
                        size: CGSize(width: 8.5,
                                     height: 8.5))
  

должно быть

 let innerFrame = CGRect(origin: CGPoint(x: 0.75,
                                        y: 0.75),
                        size: CGSize(width: 8.5,
                                     height: 8.5))
  

8.5 0.75 0.75 = 10, не 8.5 1.5 1.5 = 11,5

исправлен центр красного круга

Комментарии:

1. Спасибо! В последнее время я был настолько погружен в сетевой код и RxSwift, что забыл материал UIKit. лол.