我有一个不透明的 UIView 和 UILabel 白色不透明颜色。我将其显示为带有边框的某些视图中的子视图。我可以在我的 UILabel's 字母中看到该边框...
顺便说一句,我尝试在我的超级视图中重叠内容,并且它的渲染效果非常好 - 所以问题仅存在于边框中。
我认为当渲染层混合超级视图的边框和 UILabel
的字母时,渲染层出现问题TagView 及其超级视图的代码:
import UIKit
import PlaygroundSupport
enum TagType {
case minimal
case rounded
case circle
}
class TagView: UIView {
var tagType: TagType = .rounded { didSet { updateUI() }}
var isSelected = false { didSet { updateUI() }}
private(set) lazy var label: UILabel = {
let label = UILabel()
label.textAlignment = .center
label.translatesAutoresizingMaskIntoConstraints = false
label.clipsToBounds = true
label.font = .systemFont(ofSize: 15, weight: .semibold)
return label
}()
override init(frame: CGRect) {
super.init(frame: frame)
setup()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
setup()
}
private var leadingLabelAnchor: NSLayoutConstraint?
private var trailingLabelAnchor: NSLayoutConstraint?
private var topLabelAnchor: NSLayoutConstraint?
private var bottomLabelAnchor: NSLayoutConstraint?
var constantValue: CGFloat {
tagType == .circle ? 12 : 8
}
var verticalInsetTop: CGFloat {
tagType == .minimal ? 3 : 5
}
var verticalInsetBottom: CGFloat {
tagType == .minimal ? 3 : 7
}
private func setup() {
clipsToBounds = true
addSubview(label)
leadingLabelAnchor = label.leadingAnchor.constraint(equalTo: leadingAnchor, constant: constantValue)
trailingLabelAnchor = label.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -constantValue)
leadingLabelAnchor?.priority = .defaultHigh
leadingLabelAnchor?.isActive = true
trailingLabelAnchor?.priority = .defaultHigh
trailingLabelAnchor?.isActive = true
topLabelAnchor = label.topAnchor.constraint(equalTo: topAnchor, constant: verticalInsetTop)
topLabelAnchor?.isActive = true
bottomLabelAnchor = label.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -verticalInsetBottom)
bottomLabelAnchor?.isActive = true
layer.borderColor = UIColor.blue.cgColor
layer.borderWidth = 1
updateUI()
}
override func layoutSubviews() {
super.layoutSubviews()
updateUI()
}
private func updateUI() {
leadingLabelAnchor?.constant = constantValue
trailingLabelAnchor?.constant = -constantValue
topLabelAnchor?.constant = verticalInsetTop
bottomLabelAnchor?.constant = -verticalInsetBottom
backgroundColor = isSelected ? .blue : .clear
label.backgroundColor = backgroundColor
label.textColor = isSelected ? .white : .blue
switch tagType {
case .minimal:
layer.cornerRadius = 10
case .rounded:
layer.cornerRadius = 12
case .circle:
layer.cornerRadius = bounds.height / 2
}
}
func configure(with text: String) {
label.text = text
}
}
final class MyControl: UIControl {
private lazy var tagView: TagView = {
let view = TagView()
return view
}()
override init(frame: CGRect) {
super.init(frame: frame)
setup()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
private func setup() {
tagView.translatesAutoresizingMaskIntoConstraints = false
tagView.isSelected = true
backgroundColor = .clear
layer.cornerRadius = 10
layer.borderWidth = 2
layer.borderColor = UIColor.blue.cgColor
addSubview(tagView)
NSLayoutConstraint.activate(
[
tagView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 8),
tagView.topAnchor.constraint(equalTo: topAnchor, constant: -16)
]
)
tagView.configure(with: "7 dayyyyy")
}
}
class MyViewController : UIViewController {
override func loadView() {
let view = UIView()
view.backgroundColor = .white
let label = UILabel()
label.frame = CGRect(x: 150, y: 200, width: 200, height: 20)
label.text = "Hello World!"
label.textColor = .black
let myControl = MyControl()
myControl.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(myControl)
NSLayoutConstraint.activate([
myControl.centerXAnchor.constraint(equalTo: view.centerXAnchor),
myControl.centerYAnchor.constraint(equalTo: view.centerYAnchor),
myControl.widthAnchor.constraint(equalToConstant: 300),
myControl.heightAnchor.constraint(equalToConstant: 50),
])
view.addSubview(label)
self.view = view
}
}
// Present the view controller in the Live View window
PlaygroundPage.current.liveView = MyViewController()
我目前找到的唯一解决方法,不应用于父视图的图层边框宽度和颜色,而是向该父视图添加带有边框的附加子视图,这样标签视图不是新背景边框视图的子视图:
final class MyControl: UIControl {
...
private func setup() {
// layer.cornerRadius = 10
// layer.borderWidth = 2
// layer.borderColor = UIColor.blue.cgColor
let backgroundView = UIView()
backgroundView.backgroundColor = .white
backgroundView.translatesAutoresizingMaskIntoConstraints = false
backgroundView.layer.cornerRadius = 10
backgroundView.layer.borderWidth = 2
backgroundView.layer.borderColor = UIColor.blue.cgColor
addSubview(backgroundView)
addSubview(tagView)
}
}