Я пытаюсь создать 2 слоя, которые накладываются друг на друга и находятся внутри пользовательского класса представления.
рисование для слоев работает отлично, но я просто не могу заставить их корректировать их расположение на основе местоположения вида, которое было установлено с помощью автоматических макетов, где вид создается в коде (без IB).
Я попытался изменить кадр слоя с помощью вызова layoutSubviews
, вот код для попытки.
import UIKit
class ProgressView: UIView {
let displayLayer: CAShapeLayer = {
let display = CAShapeLayer()
display.strokeColor = UIColor.red.cgColor
display.lineWidth = 8.0
display.lineCap = CAShapeLayerLineCap.round
display.fillColor = UIColor.clear.cgColor
display.strokeEnd = 0.5
return display
}()
let trackLayer: CAShapeLayer = {
let track = CAShapeLayer()
track.strokeColor = UIColor.lightGray.cgColor
track.lineWidth = 6.0
track.lineCap = CAShapeLayerLineCap.round
track.fillColor = UIColor.clear.cgColor
return track
}()
override init(frame: CGRect) {
super.init(frame: frame)
let progressCircle = UIBezierPath(arcCenter: .zero, radius: 50, startAngle: 0, endAngle: CGFloat.pi * 2, clockwise: true)
displayLayer.path = progressCircle.cgPath
trackLayer.path = progressCircle.cgPath
layer.addSublayer(trackLayer)
layer.addSublayer(displayLayer)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func layoutSubviews() {
super.layoutSubviews()
displayLayer.frame = bounds
trackLayer.frame = bounds
}
}
После некоторых исследований я также попробовал подход KVO и использовал следующий код:
import UIKit
class ProgressView: UIView {
let displayLayer: CAShapeLayer = {
let display = CAShapeLayer()
display.strokeColor = UIColor.red.cgColor
display.lineWidth = 8.0
display.lineCap = CAShapeLayerLineCap.round
display.fillColor = UIColor.clear.cgColor
display.strokeEnd = 0.5
return display
}()
let trackLayer: CAShapeLayer = {
let track = CAShapeLayer()
track.strokeColor = UIColor.lightGray.cgColor
track.lineWidth = 6.0
track.lineCap = CAShapeLayerLineCap.round
track.fillColor = UIColor.clear.cgColor
return track
}()
override init(frame: CGRect) {
super.init(frame: frame)
let progressCircle = UIBezierPath(arcCenter: .zero, radius: 50, startAngle: 0, endAngle: CGFloat.pi * 2, clockwise: true)
displayLayer.path = progressCircle.cgPath
trackLayer.path = progressCircle.cgPath
layer.addSublayer(trackLayer)
layer.addSublayer(displayLayer)
self.addObserver(self, forKeyPath: #keyPath(ProgressView.bounds), options: .new, context: nil)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
if keyPath == #keyPath(ProgressView.bounds) {
displayLayer.frame = self.bounds
trackLayer.frame = self.bounds
}
}
}
В каждом примере я продолжаю получать один и тот же результат с показом следующего. Помните, что фиолетовая коробка - это ProgressView
, где я ожидаю, что два слоя будут внутри.
Я продолжаю смотреть на это и думаю, что есть что-то простое, что я упускаю или делаю неправильно, и я просто не вижу этого.
Я поместил оператор print в observeValue
, а также layoutSubviews
, чтобы убедиться, что они вызывались и это работало.
Вот что я вижу:
![enter image description here](https://i.stack.imgur.com/7K9X4.png)
Спасибо заранее.