斯威夫特:纽扣圆角打破矛盾 [英] Swift: Button round corner breaks contraints

查看:84
本文介绍了斯威夫特:纽扣圆角打破矛盾的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个通过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.

无论哪种方式,都可以在情节提要和@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屋!

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