删除渐变时渐变按钮崩溃 [英] Gradient Button Crashed when Removing Gradient

查看:20
本文介绍了删除渐变时渐变按钮崩溃的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我是学习 Swift 的新手,我在删除按钮渐变背景时遇到了麻烦,从技术上讲,我可以删除"它,但它不稳定,如果多次点击会崩溃.我猜这与子层没有被安全"删除有关,但我环顾四周,只是想不通.

So I'm new at learning Swift and I'm having trouble with removing the button gradient background, technically I am able to "remove" it but it's not stable and crashes if tapped multiple times. My guess it has something to do with the sublayer not being removed "safely" but I looked around and just can't figure it out.

@IBAction func button(_ sender: UIButton) {
    sender.setTitleColor(.systemBackground, for: .selected)
    sender.isSelected = !sender.isSelected
    if sender.isSelected {
        sender.layer.borderWidth = 0
        sender.applyGradient(colors: [ #colorLiteral(red: 0.5098039216, green: 0.8431372549, blue: 0.5254901961, alpha: 1) , #colorLiteral(red: 0.3058823529, green: 0.6941176471, blue: 0.3215686275, alpha: 1) ], radius: 10)
    } else {
        sender.layer.borderWidth = 1
        sender.layer.sublayers!.remove(at: 1)   // this not stable, cause crash if trigger repeatedly
    }
}

<小时>

extension UIButton {
    func applyGradient(colors: [CGColor], radius: CGFloat = 0, startGradient: CGPoint = CGPoint(x: 0.5, y: 0.0), endGradient: CGPoint = CGPoint(x: 0.5, y: 1.0)) {
        let gradientLayer = CAGradientLayer()
        gradientLayer.cornerRadius = radius
        gradientLayer.colors = colors
        gradientLayer.startPoint = startGradient
        gradientLayer.endPoint = endGradient
        gradientLayer.frame = self.bounds
        self.layer.insertSublayer(gradientLayer, at: 0)
    }
}

推荐答案

你可以给你的 CALayer 一个名字,这样你就可以在删除之前找到图层的索引:

You can give your CALayer a name this way you can find the index of your layer before removing it:

extension UIButton {
    func applyGradient(colors: [CGColor], radius: CGFloat = 0, startGradient: CGPoint = .init(x: 0.5, y: 0), endGradient: CGPoint = .init(x: 0.5, y: 1)) {
        // check first if there is already a gradient layer to avoid adding more than one
        if let gradientLayer = layer.sublayers?.first(where: {$0.name == "gradient" }) as? CAGradientLayer {
            gradientLayer.cornerRadius = radius
            gradientLayer.colors = colors
            gradientLayer.startPoint = startGradient
            gradientLayer.endPoint = endGradient
            gradientLayer.frame = bounds
        // if not found create a new gradient layer
        } else {
            let gradientLayer = CAGradientLayer()
            gradientLayer.name = "gradient"
            gradientLayer.cornerRadius = radius
            gradientLayer.colors = colors
            gradientLayer.startPoint = startGradient
            gradientLayer.endPoint = endGradient
            gradientLayer.frame = bounds
            layer.insertSublayer(gradientLayer, at: 0)
        }
    }
}

<小时>

@IBAction func button(_ sender: UIButton) {
    sender.setTitleColor(.systemBackground, for: .selected)
    sender.isSelected.toggle()
    if sender.isSelected {
        sender.layer.borderWidth = 0
        sender.applyGradient(colors: [ #colorLiteral(red: 0.5098039216, green: 0.8431372549, blue: 0.5254901961, alpha: 1) , #colorLiteral(red: 0.3058823529, green: 0.6941176471, blue: 0.3215686275, alpha: 1) ], radius: 10)
    } else {
        sender.layer.borderWidth = 1
        if let firstIndex = sender.layer.sublayers?.firstIndex(where: {$0.name == "gradient" }) {
            sender.layer.sublayers?.remove(at: firstIndex)
        }
    }
}

这篇关于删除渐变时渐变按钮崩溃的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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