IBDesignable 在添加到 UIStackView 时不起作用
IBDesignable not working when added to UIStackView
我有这个相当简单的 IBDesignable
RoundedLabel。它在 Interface Builder 中和在模拟器中 运行 时呈现良好。如果我将视图添加到 UIStackView
,即使它在 IB 中呈现良好,角半径仅应用于左上角。
import UIKit
@IBDesignable class RoundedLabel: UILabel {
@IBInspectable var cornerRadius : CGFloat = 46 {
didSet {
self.drawTheLabel()
}
}
@IBInspectable var roundRightCorners : Bool = false {
didSet {
self.drawTheLabel()
}
}
@IBInspectable var roundLeftCorners : Bool = false {
didSet {
self.drawTheLabel()
}
}
@IBInspectable var borderRadius : CGFloat = 3 {
didSet {
self.layer.borderWidth = borderRadius
}
}
@IBInspectable var borderColor : UIColor = .black {
didSet {
self.layer.borderColor = borderColor.cgColor
}
}
private func drawTheLabel() {
var tCorners : UIRectCorner = []
if roundRightCorners {
tCorners.insert(.topRight)
tCorners.insert(.bottomRight)
}
if roundLeftCorners {
tCorners.insert(.bottomLeft)
tCorners.insert(.topLeft)
}
let path = UIBezierPath(roundedRect:self.bounds,
byRoundingCorners:tCorners,
cornerRadii: CGSize(width: cornerRadius, height: cornerRadius))
let maskLayer = CAShapeLayer()
maskLayer.path = path.cgPath
self.layer.mask = maskLayer
self.layer.masksToBounds = true
}
}
不在uistackview
时的视图
添加到 uistackview
时的视图
问题出在这一行:
let path = UIBezierPath(roundedRect:self.bounds,
在 self
实际上 有 正确的 bounds
之前,该行毫无意义。但是在 你 调用 drawTheLabel
的时候,它 还没有正确的 bounds
。 (它可能是 1000x1000 或其他一些无意义的大小;您可以轻松 log/debug 并找出答案。)您正在调用 drawTheLabel
太快 ,在堆栈视图显示之前对其排列的子视图执行布局。
因此,您添加的遮罩对于最终尺寸的视图来说太大了,您只能看到遮罩的左上角;遮罩的其他角都偏向右侧和底部,对视图没有影响,因为它们不重叠。
您必须覆盖 layoutSubviews
并调用 super,然后 drawTheLabel()
这将在框架更改时应用圆角效果。
我有这个相当简单的 IBDesignable
RoundedLabel。它在 Interface Builder 中和在模拟器中 运行 时呈现良好。如果我将视图添加到 UIStackView
,即使它在 IB 中呈现良好,角半径仅应用于左上角。
import UIKit
@IBDesignable class RoundedLabel: UILabel {
@IBInspectable var cornerRadius : CGFloat = 46 {
didSet {
self.drawTheLabel()
}
}
@IBInspectable var roundRightCorners : Bool = false {
didSet {
self.drawTheLabel()
}
}
@IBInspectable var roundLeftCorners : Bool = false {
didSet {
self.drawTheLabel()
}
}
@IBInspectable var borderRadius : CGFloat = 3 {
didSet {
self.layer.borderWidth = borderRadius
}
}
@IBInspectable var borderColor : UIColor = .black {
didSet {
self.layer.borderColor = borderColor.cgColor
}
}
private func drawTheLabel() {
var tCorners : UIRectCorner = []
if roundRightCorners {
tCorners.insert(.topRight)
tCorners.insert(.bottomRight)
}
if roundLeftCorners {
tCorners.insert(.bottomLeft)
tCorners.insert(.topLeft)
}
let path = UIBezierPath(roundedRect:self.bounds,
byRoundingCorners:tCorners,
cornerRadii: CGSize(width: cornerRadius, height: cornerRadius))
let maskLayer = CAShapeLayer()
maskLayer.path = path.cgPath
self.layer.mask = maskLayer
self.layer.masksToBounds = true
}
}
不在uistackview
添加到 uistackview
问题出在这一行:
let path = UIBezierPath(roundedRect:self.bounds,
在 self
实际上 有 正确的 bounds
之前,该行毫无意义。但是在 你 调用 drawTheLabel
的时候,它 还没有正确的 bounds
。 (它可能是 1000x1000 或其他一些无意义的大小;您可以轻松 log/debug 并找出答案。)您正在调用 drawTheLabel
太快 ,在堆栈视图显示之前对其排列的子视图执行布局。
因此,您添加的遮罩对于最终尺寸的视图来说太大了,您只能看到遮罩的左上角;遮罩的其他角都偏向右侧和底部,对视图没有影响,因为它们不重叠。
您必须覆盖 layoutSubviews
并调用 super,然后 drawTheLabel()
这将在框架更改时应用圆角效果。