проблема с добавлением слоя вокруг границы кругового вида

#ios #view #calayer #uibezierpath

#iOS #Вид #calayer #uibezierpath

Вопрос:

Я добавляю круговой слой вокруг моего кругового вида и устанавливаю его position в центр вида, но слой добавляется в другом положении. Ниже приведен код.

 class CustomView: UIView {
    
    let outerLayer = CAShapeLayer()
    
    required init?(coder: NSCoder) {
        super.init(coder: coder)
        self.layer.addSublayer(outerLayer)
    }
    override func layoutSubviews() {
        super.layoutSubviews()
        self.backgroundColor = UIColor.systemBlue
        self.layer.cornerRadius = self.bounds.height/2
        self.layer.borderWidth = 2.0
        self.layer.borderColor = UIColor.white.cgColor

        let outerLayerFrame = self.bounds.insetBy(dx: -5.0, dy: -5.0)
        outerLayer.frame = outerLayerFrame
        
        let path = UIBezierPath(ovalIn: outerLayerFrame)
        outerLayer.path = path.cgPath
        outerLayer.position = self.center

        outerLayer.strokeColor = UIColor.systemBlue.cgColor
        outerLayer.fillColor = UIColor.clear.cgColor
        outerLayer.lineWidth = 3
        
    }
}
  

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

Может кто-нибудь, пожалуйста, сказать мне, что здесь не так.

Ответ №1:

Вы хотите установить свойства своего слоя (ов) при создании экземпляра / инициализации вида, но его размер может (и обычно меняется) изменяться между тем и когда автоматическая компоновка настраивает его в соответствии с текущими размерами устройства.

В отличие от UIView самого по себе, слои не изменяют размер автоматически.

Итак, вы хотите задать контуры обрамления и слоев в layoutSubviews() :

 class CustomView: UIView {
    
    let outerLayer = CAShapeLayer()

    override init(frame: CGRect) {
        super.init(frame: frame)
        configure()
    }
    required init?(coder: NSCoder) {
        super.init(coder: coder)
        configure()
    }

    // layoutSubviews is where you want to set your size
    //  and corner radius values
    override func layoutSubviews() {
        super.layoutSubviews()

        // make self "round"
        self.layer.cornerRadius = self.bounds.height/2

        // add a round path for outer layer
        let path = UIBezierPath(ovalIn: bounds)
        outerLayer.path = path.cgPath
        
    }
    
    private func configure() {
        
        self.backgroundColor = UIColor.systemBlue
        
        // setup layer properties here
        self.layer.borderWidth = 2.0
        self.layer.borderColor = UIColor.white.cgColor
        
        outerLayer.strokeColor = UIColor.systemBlue.cgColor
        outerLayer.fillColor = UIColor.clear.cgColor
        outerLayer.lineWidth = 3
        
        // add the sublayer here
        self.layer.addSublayer(outerLayer)

    }
    
}
  

Результат (для вида установлено значение 120 x 120 точек):

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

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

1. Я знаю, я только предполагал внести изменения, связанные с рамками и границами, в layoutSubviews. У меня просто было это в одном месте, чтобы разобраться со своей проблемой. Однако, увидев ваш код, я понял, что мне никогда не приходилось указывать позицию. Установления границ было бы достаточно. Спасибо вам за лучшее решение.

Ответ №2:

Итак, я понял, что именно из-за положения слой не выровнен по центру.

Вот решение, я подумал-

 class CustomView: UIView {
    
    let outerLayer = CAShapeLayer()
    
    required init?(coder: NSCoder) {
        super.init(coder: coder)
        self.layer.addSublayer(outerLayer)
    }
    override func layoutSubviews() {
        super.layoutSubviews()
        self.backgroundColor = UIColor.systemBlue
        self.layer.cornerRadius = self.bounds.height/2
        self.layer.borderWidth = 2.0
        self.layer.borderColor = UIColor.white.cgColor

        let outerLayerBounds = self.bounds.insetBy(dx: -5.0, dy: -5.0)
        outerLayer.bounds = outerLayerBounds // should be bounds not frame
      
        let path = UIBezierPath(ovalIn: outerLayerBounds)
        outerLayer.path = path.cgPath
        outerLayer.position = CGPoint(x: outerLayerBounds.midX , y: outerLayerBounds.midY) //self.center doesn't center the layer, had to calculate the center of the layer manually

        outerLayer.strokeColor = UIColor.systemBlue.cgColor
        outerLayer.fillColor = UIColor.clear.cgColor
        outerLayer.lineWidth = 3
    }
   
}