删除渐变时渐变按钮崩溃
Gradient Button Crashed when Removing Gradient
所以我是新手 Swift,我在删除按钮渐变背景时遇到了问题,从技术上讲我可以 "remove" 但它不稳定,如果点击多次会崩溃次。我猜这与子层没有被删除有关"safely"但我环顾四周,就是想不通。
@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)
}
}
它正在崩溃,因为您试图强行删除不存在的内容,请检查它是否存在,然后尝试将其删除。方法如下:
@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
if sender.layer.sublayers?.count > 1 {
sender.layer.sublayers?.remove(at: 1)
}
}
}
你可以给你的 CALayer 一个名字这样你可以在删除它之前找到你的层的索引:
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: {[=10=].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: {[=11=].name == "gradient" }) {
sender.layer.sublayers?.remove(at: firstIndex)
}
}
}
所以我是新手 Swift,我在删除按钮渐变背景时遇到了问题,从技术上讲我可以 "remove" 但它不稳定,如果点击多次会崩溃次。我猜这与子层没有被删除有关"safely"但我环顾四周,就是想不通。
@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)
}
}
它正在崩溃,因为您试图强行删除不存在的内容,请检查它是否存在,然后尝试将其删除。方法如下:
@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
if sender.layer.sublayers?.count > 1 {
sender.layer.sublayers?.remove(at: 1)
}
}
}
你可以给你的 CALayer 一个名字这样你可以在删除它之前找到你的层的索引:
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: {[=10=].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: {[=11=].name == "gradient" }) {
sender.layer.sublayers?.remove(at: firstIndex)
}
}
}