IBOutlet初始化中的UIView框架中心不正确

时间:2015-11-16 02:05:16

标签: ios swift uiview autolayout

我有一个进度条,它应该在视图的中心渲染,但由于自动布局而偏离中心。

class ProgressView: UIView {
    private let progressLayer: CAShapeLayer = CAShapeLayer()

    private var progressLabel: UILabel

    required init?(coder aDecoder: NSCoder) {
        progressLabel = UILabel()
        super.init(coder: aDecoder)
        createProgressLayer()
        createLabel()
    }

    override init(frame: CGRect) {
        progressLabel = UILabel()
        super.init(frame: frame)
        createProgressLayer()
        createLabel()
    }

    private func createProgressLayer() {
        let startAngle = CGFloat(3*M_PI_2)
        let endAngle = CGFloat(M_PI * 2 + 3*M_PI_2)
        let centerPoint = CGPointMake(CGRectGetWidth(bounds)/2, CGRectGetHeight(bounds)/2)

        let gradientMaskLayer = gradientMask()
        progressLayer.path = UIBezierPath(arcCenter:centerPoint, radius: CGRectGetWidth(frame)/2-8, startAngle:startAngle, endAngle:endAngle, clockwise: true).CGPath
        progressLayer.backgroundColor = UIColor.clearColor().CGColor
        progressLayer.fillColor = nil
        progressLayer.strokeColor = UIColor.blackColor().CGColor
        progressLayer.lineWidth = 4.0
        progressLayer.strokeStart = 0.0
        progressLayer.strokeEnd = 0.0

        gradientMaskLayer.mask = progressLayer
        layer.addSublayer(gradientMaskLayer)
    }

    func animateProgressView() {
        progressLayer.strokeEnd = 0.0

        let animation = CABasicAnimation(keyPath: "strokeEnd")
        animation.fromValue = CGFloat(0.0)
        animation.toValue = CGFloat(1.0)
        animation.duration = 2.0
        animation.delegate = self
        animation.removedOnCompletion = false
        animation.additive = true
        animation.fillMode = kCAFillModeForwards
        progressLayer.addAnimation(animation, forKey: "strokeEnd")
    }
}

此代码的调用如下:

class MainPageController: UIViewController {

    @IBOutlet var progressView : ProgressView!

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    override func viewDidLayoutSubviews() {
        progressView.animateProgressView()
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
}

并最终将圆圈偏离中心。如果我手动编辑圆心,则右边和底部条似乎被切断。如果我关闭自动布局,它可以正常工作。我做错了什么?

Circle is off-center

故事板:

Storyboard for view

2 个答案:

答案 0 :(得分:2)

感谢您从故事板发布约束,我现在可以看到它是什么造成的。

ProgessView设置有两个约束,一个用于保持正方形,另一个用于使其高度为视图高度的1/3。这意味着您在故事板中看到的视图大小与设备中的视图大小不同。

从故事板加载视图时会调用

init?(coder aDecoder: NSCoder)。它在自动布局运行之前调用,因此您为boundsframe获得的值基于故事板中200x200的大小。然后自动布局运行并确定您的手机(看起来像iPhone 6)的大小应为222x222。根据您的屏幕截图,您的进度视图的右侧和底部看起来有大约22个额外空间。

在“自动布局”将视图设置为适当大小后,您要做的是调整进度图层的大小。通过从layoutSubviews

移动一些行,最好的位置是createProgressLayer
func layoutSubviews() {
    let startAngle = CGFloat(3*M_PI_2)
    let endAngle = CGFloat(M_PI * 2 + 3*M_PI_2)
    let centerPoint = CGPointMake(bounds.width/2, bounds.height/2)

    progressLayer.path = UIBezierPath(arcCenter:centerPoint, radius: frame.width/2-8, startAngle:startAngle, endAngle:endAngle, clockwise: true).CGPath
}

答案 1 :(得分:0)

在Interface Builder中,将Progress View的内容模式更改为重绘,并覆盖drawRect并从那里调用createProgressLayer。