我正在尝试创建两个层叠在一起的层,它们都在一个自定义视图类中。
图层的绘图工作得很好,但我无法让它们根据视图的位置来调整它们的位置,该视图是使用自动布局设置的,视图是在代码中创建的(无IB)。
我尝试过通过调用layoutSubviews来更改层的框架,这里是try的代码。
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,在那里,我期望两个层在里面。
我一直在看这个,认为有一些简单的东西,我错过或做错了,我只是看不见它。
我在observeValue和layoutSubviews中都放置了print语句,以确保它们被调用了,并且这是有效的。
以下是我所看到的:

提前谢谢。
发布于 2018-11-05 04:43:07
您需要如下所示提供正确的arcCenter,而不需要为shapLayer设置一个frame。
override func layoutSubviews() {
super.layoutSubviews()
let center = CGPoint(x: bounds.midX, y: bounds.midY)
let progressCircle = UIBezierPath(arcCenter: center, radius: 50, startAngle: 0, endAngle: CGFloat.pi * 2, clockwise: true)
displayLayer.path = progressCircle.cgPath
trackLayer.path = progressCircle.cgPath
}结果

注意:我使用了第一个没有KVO的ProgressView类。
https://stackoverflow.com/questions/53148356
复制相似问题