Swift中的UIView子视图在自定义UIView子类中无法圆角化

3

问候stackoverflow。

我正在尝试使用彩色的子视图和圆角构建“靶心”类型的视图。问题是,只有我的第一个子视图的角被圆角化了,而内部视图仍然是正方形。黑色视图是自定义视图的子视图。红色视图是黑色视图的子视图,黄色视图是红色视图的子视图。非常简单的层级结构。

结果看起来像这样:

Bullseye with squares instead of circles

我手动添加视图并设置它们的约束。我的测试应用程序中,ThreeCircleView 死中心在视图控制器中,X,Y居中,宽度和高度固定。我在 didLayoutSubViews 中实际进行角的圆角处理,因为视图的大小可能会改变,因此必须重新调整角的大小。

我编写了一个测试视图来隔离此问题,以下是该视图:

class ThreeCircleView: UIView {

    var outerCircle: UIView = UIView()
    var middleCircle: UIView = UIView()
    var innerCircle: UIView = UIView()
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        translatesAutoresizingMaskIntoConstraints = false
        addSubViews()
    }

    required init?(coder: NSCoder) {
        super.init(coder: coder)
        translatesAutoresizingMaskIntoConstraints = false
        addSubViews()
    }

    func addSubViews() {
        outerCircle.backgroundColor = .black
        middleCircle.backgroundColor = .red
        innerCircle.backgroundColor = .yellow
    
        self.addSubview(outerCircle)
        outerCircle.addSubview(middleCircle)
        middleCircle.addSubview(innerCircle)
        
        let outerCenterY = outerCircle.centerYAnchor.constraint(equalTo: self.centerYAnchor)
        let outerCenterX = outerCircle.centerXAnchor.constraint(equalTo: self.centerXAnchor)
        let outerCenterWidth = outerCircle.widthAnchor.constraint(equalTo: self.widthAnchor, constant: -50.0 )
        let outerCenterHeight = outerCircle.heightAnchor.constraint(equalTo: self.heightAnchor, constant: -50.0 )
        outerCircle.translatesAutoresizingMaskIntoConstraints = false
        NSLayoutConstraint.activate([outerCenterY,outerCenterX,outerCenterWidth,outerCenterHeight])
        
        self.setNeedsLayout()
        let middleCenterY = middleCircle.centerYAnchor.constraint(equalTo: self.centerYAnchor)
        let middleCenterX = middleCircle.centerXAnchor.constraint(equalTo: self.centerXAnchor)
        let middleCenterWidth = middleCircle.widthAnchor.constraint(equalTo: self.widthAnchor, constant: -100.0 )
        let middleCenterHeight = middleCircle.heightAnchor.constraint(equalTo: self.heightAnchor, constant: -100.0 )
        middleCircle.translatesAutoresizingMaskIntoConstraints = false
        NSLayoutConstraint.activate([middleCenterY,middleCenterX,middleCenterWidth,middleCenterHeight])

        let innerCenterY = innerCircle.centerYAnchor.constraint(equalTo: self.centerYAnchor)
        let innerCenterX = innerCircle.centerXAnchor.constraint(equalTo: self.centerXAnchor)
        let innerCenterWidth = innerCircle.widthAnchor.constraint(equalTo: self.widthAnchor, constant: -150.0 )
        let innerCenterHeight = innerCircle.heightAnchor.constraint(equalTo: self.heightAnchor, constant: -150.0 )
        innerCircle.translatesAutoresizingMaskIntoConstraints = false
        NSLayoutConstraint.activate([innerCenterY,innerCenterX,innerCenterWidth,innerCenterHeight])

    }

    func makeCircle(v:UIView) {
        v.layer.cornerRadius = v.frame.size.width * 0.50
        v.clipsToBounds = true
    }
    
    override func layoutSubviews() {
        super.layoutSubviews()
        makeCircle(v: outerCircle)
        makeCircle(v: middleCircle)
        makeCircle(v: innerCircle)
    }
    
}

为什么不使用UIBezierPath绘制几个圆呢? - El Tomato
或者我可以使用一个图像,我正在尝试制作一个黑色圆圈、然后是白色圆圈、接着是黑色圆圈的记录。现在,我真的想知道为什么我的角没有被圆角化。这已经变成了个人问题。 - Tom Schulz
1个回答

7

使它看起来正常的简单方法是在makeCircle(v:UIView)方法内添加layoutIfNeeded()调用。这将确保所有视图框架在应用可视化更改之前得到正确更新:

func makeCircle(v:UIView) {
        v.layoutIfNeeded()
        v.layer.cornerRadius = v.frame.size.width * 0.50
        v.clipsToBounds = true
    }

谢谢你,Petr。这个细节超出了我凌晨三点的大脑所能理解的范畴,你的回答让我非常清醒地醒来。真的非常感谢。 - Tom Schulz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接