斯威夫特:按钮圆角打破约束

时间:2017-11-27 16:42:50

标签: ios swift autolayout rounded-corners

我有一个通过xib加载自定义单元格的tableview,在该单元格中我有一个状态按钮,右下角应该是圆角的。按钮具有约束尾随/前导/底部空间到superview = 0和height = 30.

enter image description here

如果没有四舍五入,它就会完美地运行,只要我绕过一个角落,例如右下角,约束就会破坏

self.btnStatus.roundCorners(corners: [.bottomRight], radius: 7.0, borderWidth: nil, borderColor: nil)

enter image description here

有些人建议调用layoutSubviews(),但它没有帮助我。

更具体地说,我已经创建了一个简单的项目,您可以在其中查看整个项目。

更正链接

enter image description here

2 个答案:

答案 0 :(得分:2)

您可以通过继承按钮并放置"舍入"来获得更可靠的结果。代码通过覆盖其layoutSubviews()函数。

首先,如果您想添加边框,则不要添加多个"边框子图层" ...所以将UIView扩展名更改为:

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子类:

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的

无论哪种方式,都要将btnStatus课程从UIButton更改为RoundedButton - 在故事板和@IBOutlet连接中。

然后将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
}

应该这样做......

答案 1 :(得分:0)

也许你的按钮重叠,因为它没有上限?尝试添加明亮边框,看看是否可以看到顶部,如果不是尝试在顶部添加约束。另外,不要给它一个静态高度,而是尝试使它与它上面的物体成比例高度(可能是你设备的屏幕尺寸导致它重叠)