使用 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),
])
}
}
我为 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),
])
}
}