我有一个表格视图,其中包含通过 xib 加载的自定义单元格,在该单元格中我有状态按钮,右下角应该是圆角的.该按钮的尾随/前导/底部空间限制为 superview=0 和 height=30.
I have a tableview with custom cell loaded via xib and in that cell I have status button which bottom right corner should be rounded. The button has constraints Trailing/Leading/Bottom space to superview=0 and height=30.
如果不四舍五入,它就可以完美地工作,只要我将一个角(例如右下角)转角,约束就会中断
Without rounding it is working perfectly, as soon as I round one corner for example bottom right the constraints breaks
self.btnStatus.roundCorners(corners: [.bottomRight], radius: 7.0, borderWidth: nil, borderColor: nil)
这里有些人建议调用 layoutSubviews() 但它没有帮助我.
Some guys here suggesting to call layoutSubviews() but it didn't helped me.
更具体地说,我创建了一个简单的项目,您可以在其中查看整个项目.
To be more specific I've created simple project where you can have a look into whole project.
正确链接
ButtonRoundCorner.zip
您可以通过将按钮子类化并通过覆盖其 layoutSubviews()
函数放置舍入"代码来获得更可靠的结果.
You can get more reliable results by subclassing your button and placing your "rounding" code by overriding its layoutSubviews()
function.
首先,如果你想添加一个边框,你不想添加多个边框子层"......所以将你的 UIView
扩展名更改为:
First, if you want to add a border, you don't want to add multiple "border sublayers" ... so change your UIView
extension to this:
extension UIView {
func roundCorners(corners: UIRectCorner, radius: CGFloat, borderWidth: CGFloat?, borderColor: UIColor?) {
let maskPath = UIBezierPath(roundedRect: self.bounds, byRoundingCorners: corners, cornerRadii: CGSize(width: radius, height: radius))
let maskLayer = CAShapeLayer()
maskLayer.frame = self.bounds
maskLayer.path = maskPath.cgPath
self.layer.mask = maskLayer
self.layer.masksToBounds = true
if (borderWidth != nil && borderColor != nil) {
// remove previously added border layer
for layer in layer.sublayers! {
if layer.name == "borderLayer" {
layer.removeFromSuperlayer()
}
}
let borderLayer = CAShapeLayer()
borderLayer.frame = self.bounds;
borderLayer.path = maskPath.cgPath;
borderLayer.lineWidth = borderWidth ?? 0;
borderLayer.strokeColor = borderColor?.cgColor;
borderLayer.fillColor = UIColor.clear.cgColor;
borderLayer.name = "borderLayer"
self.layer.addSublayer(borderLayer);
}
}
}
接下来,添加一个UIButton
子类:
Next, add a UIButton
subclass:
class RoundedButton: UIButton {
var corners: UIRectCorner?
var radius = CGFloat(0.0)
var borderWidth = CGFloat(0.0)
var borderColor: UIColor?
override func layoutSubviews() {
super.layoutSubviews()
// don't apply mask if corners is not set, or if radius is Zero
guard let _corners = corners, radius > 0.0 else {
return
}
roundCorners(corners: _corners, radius: radius, borderWidth: borderWidth, borderColor: borderColor)
}
}
这给您带来了一些好处:1) 当按钮框架发生变化时(例如,旋转设备),它将更新其遮罩层框架,以及 2) 您可以从自定义单元类 中设置这些值或来自 cellForRowAt.
This gives you a couple benefits: 1) It will update its mask layer frame when the button frame changes (rotating the device, for example), and 2) you could set these values either from your custom cell class or from cellForRowAt.
无论哪种方式,将您的 btnStatus
类从 UIButton
更改为 RoundedButton
- 在情节提要和 @IBOutlet
连接.
Either way, change your btnStatus
class from UIButton
to RoundedButton
- both in your storyboard and the @IBOutlet
connection.
然后将您的 CustomTableViewCell
更改为:
Then change your CustomTableViewCell
to this:
class CustomTableViewCell: UITableViewCell {
@IBOutlet weak var btnStatus: RoundedButton!
override func awakeFromNib() {
super.awakeFromNib()
// set up corner maskign
btnStatus.corners = .bottomRight
btnStatus.radius = 7.0
// set if desired
// btnStatus.borderWidth = 2.0
// btnStatus.borderColor = .blue
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
}
最后,您的 cellForRowAt
函数变为:
And finally, your cellForRowAt
function becomes:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = self.tableView.dequeueReusableCell(withIdentifier: "customCell", for: indexPath) as! CustomTableViewCell
return cell
}
应该可以的...
这篇关于Swift:按钮圆角打破限制的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!