ios - 自定义 UIView 的 subview 的 x 框架位置错误

标签 ios uiview

我有一个自定义 UIView,如下所示:

import UIKit

class MainLogoAnimationView: UIView {

    @IBOutlet var customView: UIView!
    var turquoiseCircle: AnimationCircleView!
    var redCircle: AnimationCircleView!
    var blueCircle: AnimationCircleView!


    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        setup()
    }

    func setup() {
        _ = Bundle.main.loadNibNamed("MainLogoAnimationView", owner: self, options: nil)?[0] as! UIView
        self.addSubview(customView)
        customView.frame = self.bounds
        setupAnimation()
    }

    let initialWidthScaleFactor: CGFloat = 0.06

    func setupAnimation() {
        let circleWidth = frame.size.width*initialWidthScaleFactor
        let yPos = frame.size.height/2 - circleWidth/2
        turquoiseCircle = AnimationCircleView(frame: CGRect(x: 0, y: yPos, width: circleWidth, height: circleWidth))
        turquoiseCircle.circleColor = UIColor(red: 137/255.0, green: 203/255.0, blue: 225/255.0, alpha: 1.0).cgColor
        turquoiseCircle.backgroundColor = UIColor.lightGray
        addSubview(turquoiseCircle)
        redCircle = AnimationCircleView(frame: CGRect(x: 100, y: yPos, width: circleWidth, height: circleWidth))
        addSubview(redCircle)
        blueCircle = AnimationCircleView(frame: CGRect(x: 200, y: yPos, width: circleWidth, height: circleWidth))
        blueCircle.circleColor = UIColor(red: 93/255.0, green: 165/255.0, blue: 213/255.0, alpha: 1.0).cgColor
        addSubview(blueCircle)
    }
}

我在界面生成器中创建了一个浅蓝色的 UIView,并将上面的 View MainLogoAnimationView 设置为其子类。如果我运行该应用程序,我会得到以下信息:

enter image description here

对于turquoiseCircle来说,框架似乎没有被放置在我设置的x = 0处。不知道我在这里做错了什么。是否是因为它是在 MainLogoAnimationView 完全初始化之前放置的,所以放置不正确?我尝试在 layoutSubviews() 中设置圆圈的框架,但这也没有任何区别。我似乎经常遇到这个问题,因为观点被放错了地方,并且认为我在这里错过了一些基本的东西。我做错了什么?

更新:

import UIKit

class MainLogoAnimationView: UIView {

    @IBOutlet var customView: UIView!
    var turquoiseCircle: AnimationCircleView!
    var redCircle: AnimationCircleView!
    var blueCircle: AnimationCircleView!


    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        setup()
    }

    func setup() {
        _ = Bundle.main.loadNibNamed("MainLogoAnimationView", owner: self, options: nil)?[0] as! UIView
        self.addSubview(customView)
        customView.frame = self.bounds
        setupAnimation()
    }

    let initialWidthScaleFactor: CGFloat = 0.2


    func setupAnimation() {
        blueCircle = AnimationCircleView()
        blueCircle.translatesAutoresizingMaskIntoConstraints = false
        blueCircle.backgroundColor = UIColor.lightGray
        blueCircle.circleColor = UIColor.blue.cgColor
        addSubview(blueCircle)

        redCircle = AnimationCircleView()
        redCircle.translatesAutoresizingMaskIntoConstraints = false
        redCircle.backgroundColor = UIColor.lightGray
        addSubview(redCircle)
    }

    override func layoutSubviews() {
        super.layoutSubviews()
        let circleWidth = bounds.size.width*initialWidthScaleFactor
        let yPos = frame.size.height/2 - circleWidth/2
        blueCircle.frame = CGRect(x: 0, y: yPos, width: circleWidth, height: circleWidth)
        redCircle.frame = CGRect(x: frame.size.width/2 - circleWidth/2, y: yPos, width: circleWidth, height: circleWidth)
    }
}

和:

导入UIKit

class AnimationCircleView: UIView {

    var circleColor = UIColor(red: 226/255.0, green: 131/255.0, blue: 125/255.0, alpha: 1.0).cgColor {
        didSet {
            shapeLayer.fillColor = circleColor
        }
    }

    override init(frame: CGRect) {
        super.init(frame: frame)
        setup()
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        setup()
    }

    let shapeLayer = CAShapeLayer()

    func setup() {
        let circlePath = UIBezierPath(ovalIn: self.bounds)
        shapeLayer.path = circlePath.cgPath
        shapeLayer.fillColor = circleColor
        shapeLayer.frame = self.bounds
        layer.addSublayer(shapeLayer)
    }

}

enter image description here

最佳答案

在init中的设置肯定会提供self.frame/self.bounds无论 View 的初始化值是什么,而不是在 View 层次结构中布局时的正确最终值。处理这个问题的最佳方法可能就像您尝试过的那样,在 init 中添加 View ,并使用属性来保留对它们的引用(您已经在这样做),然后在 -layoutSubviews() 中设置框架。 .

它可能在 -layoutSubviews() 中不起作用的原因对于创建后的每个 View ,您需要调用 .translatesAutoresizingMaskIntoConstraints = false 。否则,对于以编程方式创建的 View ,当作为 subview 添加时,系统将为值创建约束,从而覆盖框架的任何设置。尝试设置一下,看看效果如何。

编辑:为了调整 CAShapeLayer 的大小,而不是添加为子层(这需要手动调整大小),因为 AnimationCirleView View 是专门的,该 View 可以由 CAShapeLayer 支持。答案见Overriding default layer type in UIView in swift

关于ios - 自定义 UIView 的 subview 的 x 框架位置错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42006395/

相关文章:

ios - 如何在 Swift 中从 SKScene 呈现 UiView

ios - 如何强制UIView(mapView)占满整个屏幕

ios - 我是否应该将 "addArrangedSubview"附在动画 block 中?

iphone - UIView动画问题(将扩展动画与收缩动画匹配)

ios - 通过 Interface Builder 更改 UIView 属性

iphone - ios - 以编程方式调整自定义 View 的大小

ios - gpx 文件中的地理定位和跟踪

ios - PerformSegueWithIdentifier 随机崩溃

ios - 如何将 UITextField 添加到 CALayer 并使其工作

ios - 如何将图像放入 Realm 数据库?