斯威夫特:纽扣圆角打破矛盾 [英] Swift: Button round corner breaks contraints
问题描述
我有一个通过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.
正确链接
推荐答案
通过子类化按钮并覆盖其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.
无论哪种方式,都可以在情节提要和@IBOutlet
连接中将btnStatus
类从UIButton
更改为RoundedButton
.
Either way, change your btnStatus
class from UIButton
to RoundedButton
- both in your storyboard and the @IBOutlet
connection.
然后将您的CustomTableViewCell
更改为此:
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
函数变为:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = self.tableView.dequeueReusableCell(withIdentifier: "customCell", for: indexPath) as! CustomTableViewCell
return cell
}
应该这样做...
这篇关于斯威夫特:纽扣圆角打破矛盾的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!