如何解决CAShapeLayer偏离中心
我一直在尝试为我的应用使用UIControl
创建一个自定义的“滑块”或旋钮。我找到了this教程,并一直在使用它来获得一些启发,但是由于它并没有真正完成我想做的事情,因此我将它更多地用作参考而非教程。无论如何,我写了下面的代码,发现我的CAShapeLayer不在我设置为自定义类CircularSelector
的实例的UIView的中心。
这是我的代码:
class CircularSelector: UIControl {
private let renderer = CircularSelectorRenderer()
override init(frame: CGRect) {
super.init(frame: frame)
commonInit()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
commonInit()
}
private func commonInit() {
renderer.updateBounds(bounds)
//layer.borderWidth = 4
// layer.borderColor = UIColor.red.cgColor
layer.addSublayer(renderer.selectorLayer)
}
}
class CircularSelectorRenderer {
let selectorLayer = CAShapeLayer()
init() {
selectorLayer.fillColor = UIColor.clear.cgColor
selectorLayer.strokeColor = UIColor.white.cgColor
//Testing
//selectorLayer.borderColor = UIColor.white.cgColor
// selectorLayer.borderWidth = 4
}
private func updateSelectorLayerPath() {
let bounds = selectorLayer.bounds
let arcCenter = CGPoint(x: bounds.midX,y: bounds.maxY)
let radius = 125
var ring = UIBezierPath(arcCenter: arcCenter,radius: CGFloat(radius),startAngle: 0.degreesToradians,endAngle: 180.degreesToradians,clockwise: false)
selectorLayer.linewidth = 10
selectorLayer.path = ring.cgPath
}
func updateBounds(_ bounds: CGRect) {
selectorLayer.bounds = bounds
selectorLayer.position = CGPoint(x: bounds.midX,y: bounds.midY)
updateSelectorLayerPath()
}
}
这就是我得到的:
当我在//Testing
的{{1}}的{{1}}行下取消注释代码时,我得到了:
灰色的UIView属于init()
类。对于我的CircularSelectorRenderer
为什么比灰度视图本身宽,以及为什么它不在灰度视图的中央,我感到困惑。为什么会发生这种情况,我该如何解决。
解决方法
问题是您在错误的位置更新了形状。视图可以(并且将)更改不同设备大小,超级视图大小,设备旋转等的大小。
当您告诉视图布局其子视图时,您想更新形状层:
class CircularSelector: UIControl {
private let renderer = CircularSelectorRenderer()
override init(frame: CGRect) {
super.init(frame: frame)
commonInit()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
commonInit()
}
private func commonInit() {
// no need to call this here
//renderer.updateBounds(bounds)
//layer.borderWidth = 4
// layer.borderColor = UIColor.red.cgColor
layer.addSublayer(renderer.selectorLayer)
}
// add this func
override func layoutSubviews() {
super.layoutSubviews()
// here is where you want to update the layer
renderer.updateBounds(bounds)
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。