Swift:按钮圆角打破限制 [英] Swift: Button round corner breaks contraints

查看:17
本文介绍了Swift:按钮圆角打破限制的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个表格视图,其中包含通过 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:按钮圆角打破限制的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆