使用 cornerRadius 时,iOS UIView 背景颜色错误

When use cornerRadius, iOS UIView background color is wrong color

我为 UIView 应用了 cornerRadius,并应用了边框颜色。 但是,我可以在角落看到错误的颜色。 下图是模拟器的放大图。

下图是调试视图层次结构。

如何解决这个问题?

class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        
        view.backgroundColor = .black
        
        let test = UIView()
        test.backgroundColor = .white
        test.layer.cornerRadius = 7
        test.layer.borderColor = UIColor.black.cgColor
        test.layer.borderWidth = 2
        
        view.addSubview(test)
        
        test.translatesAutoresizingMaskIntoConstraints = false
        
        NSLayoutConstraint.activate([
            test.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 15),
            test.topAnchor.constraint(equalTo: view.topAnchor, constant: 50),
            test.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -15),
            test.heightAnchor.constraint(equalToConstant: 40)
        ])
    }
}

我希望我对你的评论是正确的,边框颜色不正确,因为你仍然在视图的外边缘看到背景色的边缘为白色。

如果是这种情况,您可以通过将视图设置为 clipsToBounds 为真来轻松摆脱它。您的代码看起来只是略有不同。

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        view.backgroundColor = .black
        
        let test = UIView()
        test.backgroundColor = .white
        test.clipsToBounds = true
        test.layer.cornerRadius = 7
        test.layer.borderColor = UIColor.black.cgColor
        test.layer.borderWidth = 2
        
        view.addSubview(test)
        
        test.translatesAutoresizingMaskIntoConstraints = false
        
        NSLayoutConstraint.activate([
            test.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 15),
            test.topAnchor.constraint(equalTo: view.topAnchor, constant: 50),
            test.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -15),
            test.heightAnchor.constraint(equalToConstant: 40)
        ])
    }
}

这应该可以解决您的边缘问题。

亲切的问候, MacUserT

好的 - 您看到的是边框 anti-aliasing 的“人工制品”...因为边框绘制在视图的 内部 上。

自从(我相信)iOS 的第一个版本以来一直如此。

使用角半径使视图变圆时,伪像更加明显:

和zoomed-in到200%:

避免这种情况的方法是使用 CAShapeLayer 和 rounded-corner UIBezierPath

这是一个快速示例视图子类,其 public 属性类似于您已经在 .layer:

上使用的属性
class ExampleView: UIView {
    public var fillColor: CGColor = UIColor.clear.cgColor {
        didSet {
            shapeLayer.fillColor = fillColor
        }
    }
    public var strokeColor: CGColor = UIColor.clear.cgColor {
        didSet {
            shapeLayer.strokeColor = strokeColor
        }
    }
    public var lineWidth: CGFloat = 0 {
        didSet {
            shapeLayer.lineWidth = lineWidth
        }
    }
    public var cornerRadius: CGFloat = 0 {
        didSet {
            shapeLayer.cornerRadius = cornerRadius
        }
    }
    private var shapeLayer: CAShapeLayer!
    override class var layerClass: AnyClass {
        return CAShapeLayer.self
    }
    override init(frame: CGRect) {
        super.init(frame: frame)
        commonInit()
    }
    required init?(coder: NSCoder) {
        super.init(coder: coder)
        commonInit()
    }
    private func commonInit() -> Void {
        shapeLayer = self.layer as? CAShapeLayer
        shapeLayer.fillColor = fillColor
        shapeLayer.strokeColor = strokeColor
        shapeLayer.lineWidth = lineWidth
    }
    override func layoutSubviews() {
        super.layoutSubviews()
        let pth = UIBezierPath(roundedRect: bounds, cornerRadius: cornerRadius)
        shapeLayer.path = pth.cgPath
    }

}

这给了我们:

然后,再次 zoomed-in 到 200%:

这是一个显示差异的示例视图控制器:

class ExampleViewController: UIViewController {
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        view.backgroundColor = .black
        
        let test = UIView()
        test.backgroundColor = .white
        test.layer.cornerRadius = 7
        test.layer.borderColor = UIColor.black.cgColor
        test.layer.borderWidth = 2
        
        
        let circleTest = UIView()
        circleTest.backgroundColor = .white
        circleTest.layer.cornerRadius = 20
        circleTest.layer.borderColor = UIColor.black.cgColor
        circleTest.layer.borderWidth = 2

        
        let myTest = ExampleView()
        myTest.backgroundColor = .white
        myTest.cornerRadius = 7
        myTest.strokeColor = UIColor.black.cgColor
        myTest.lineWidth = 2
        

        let myCircleTest = ExampleView()
        myCircleTest.backgroundColor = .white
        myCircleTest.cornerRadius = 20
        myCircleTest.strokeColor = UIColor.black.cgColor
        myCircleTest.lineWidth = 2
        

        view.addSubview(test)
        view.addSubview(circleTest)
        view.addSubview(myTest)
        view.addSubview(myCircleTest)

        test.translatesAutoresizingMaskIntoConstraints = false
        circleTest.translatesAutoresizingMaskIntoConstraints = false
        myTest.translatesAutoresizingMaskIntoConstraints = false
        myCircleTest.translatesAutoresizingMaskIntoConstraints = false

        NSLayoutConstraint.activate([
            test.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 15),
            test.topAnchor.constraint(equalTo: view.topAnchor, constant: 50),
            test.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -170),
            test.heightAnchor.constraint(equalToConstant: 40),

            circleTest.topAnchor.constraint(equalTo: test.bottomAnchor, constant: 8),
            circleTest.centerXAnchor.constraint(equalTo: view.centerXAnchor),
            circleTest.heightAnchor.constraint(equalToConstant: 40),
            circleTest.widthAnchor.constraint(equalTo: circleTest.heightAnchor),

            myTest.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 15),
            myTest.topAnchor.constraint(equalTo: circleTest.bottomAnchor, constant: 8),
            myTest.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -170),
            myTest.heightAnchor.constraint(equalToConstant: 40),

            myCircleTest.topAnchor.constraint(equalTo: myTest.bottomAnchor, constant: 8),
            myCircleTest.centerXAnchor.constraint(equalTo: view.centerXAnchor),
            myCircleTest.heightAnchor.constraint(equalToConstant: 40),
            myCircleTest.widthAnchor.constraint(equalTo: myCircleTest.heightAnchor),
            
        ])
    }

}