微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

CAShapeLayer偏离中心

如何解决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()
         
     }
     
 }

这就是我得到的:

Simulator

当我在//Testing的{​​{1}}的{​​{1}}行下取消注释代码时,我得到了:

Simulator

灰色的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 举报,一经查实,本站将立刻删除。