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

标签 ios swift uiview autolayout

我有一个进度条,它应该呈现在 View 的中心,但由于自动布局而最终偏离中心。

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:

Storyboard for view

最佳答案

感谢您发布 Storyboard 中的约束,我现在知道是什么原因造成的。

ProgessView 设置有两个约束,一个是保持正方形,另一个是使其高度为 View 高度的 1/3。这意味着您在 Storyboard 中看到的 View 大小与设备上的 View 大小不同。

init?(coder aDecoder: NSCoder) 在从 Storyboard加载 View 时调用。它在自动布局运行之前调用,因此您获得的 boundsframe 的值基于 Storyboard中的大小,即 200x200。然后自动布局运行并确定您的手机(看起来像 iPhone 6)的尺寸应该是 222x222。根据您的屏幕截图,您的进度 View 的右侧和底部似乎有大约 22 磅的额外空间。


您需要做的是在自动布局将您的 View 设置为合适的大小后调整进度层的大小。最好的做法是在 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
}

关于ios - IBOutlet 初始化中的 UIView 框架中心不正确,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33727491/

相关文章:

iphone - 使用 NSMutableURLRequest 通过 http post 发送文件时出现网络错误

swift - 当我在 ubuntu 16.04 中使用 self swift2 时,无法将类型 'String' 的值转换为强制类型 'NSString'

swift - 有没有办法模拟 View ?

ios - Sinch iOS - 'NSInvalidArgumentException' , '-[UIDevice reb_platform] : unrecognized selector

ios - CIRadialGradient 减小图像尺寸

ios - didUpdateLocations 在 Swift 3 中不起作用

ios - CATiledLayer:如何仅重新加载一些图 block ?

ios - Swift:通过其 super View 窗口中的平移手势更改(翻译)UIView 位置

ios - 从 xc10 > xc11 迁移 SceneKit 应用程序,我遇到 "xcrun: error: unable to find utility "scntool",不是开发人员工具或在 PATH 中"

ios - 在选定的行快速推送 segue 3