首页 > 解决方案 > 当按钮的背景颜色为渐变时,标题消失了

问题描述

这是我的自定义按钮:

class GradientButton: UIButton {
    private var colors: [UIColor] = [.white]
    private var direction: GradientDirection = .leftToRight

    override init(frame: CGRect) {
        super.init(frame: frame)

    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    init(colors: [UIColor], direction: GradientDirection) {
        self.init()

        self.colors = colors
        self.direction = direction
    }

    override func layoutSubviews() {
        self.backgroundColor = UIColor.gradientColorWith(bounds: self.bounds, colors: self.colors, direction: self.direction)
    }
}

和渐变色:

enum GradientDirection {
    case topToBottom         
    case leftToRight         
    case bottomToTop         
    case rightToLeft         
    case leftTopToRightBottom
    case leftBottomToRightTop
    case rightTopToLeftBottom
    case RightBottomToLeftTop
}
extension UIColor {
    static func gradientColorWith(bounds: CGRect, colors: [UIColor], direction: GradientDirection) -> UIColor {

        var cgColorArray: [CGColor] = []
        for color in colors {
            cgColorArray.append(color.cgColor)
        }

        UIGraphicsBeginImageContextWithOptions(bounds.size, true, 1)
        guard let context = UIGraphicsGetCurrentContext() else { return .white }
        context.saveGState();
        let colorSpace = colors.last?.cgColor.colorSpace
        let gradient = CGGradient.init(colorsSpace: colorSpace, colors: cgColorArray as CFArray, locations: nil)!

        var startPoint = CGPoint.zero
        var endPoint = CGPoint.zero

        let width = bounds.size.width
        let height = bounds.size.height

        switch direction {
        case .topToBottom:
            startPoint = CGPoint.init(x: 0, y: 0)
            endPoint = CGPoint.init(x: 0, y: height)
        case .leftToRight:
            startPoint = CGPoint.init(x: 0, y: 0)
            endPoint = CGPoint.init(x: width, y: 0)
        case .bottomToTop:
            startPoint = CGPoint.init(x: 0, y: height)
            endPoint = CGPoint.init(x: 0, y: 0)
        case .rightToLeft:
            startPoint = CGPoint.init(x: width, y: 0)
            endPoint = CGPoint.init(x: 0, y: 0)
        case .leftTopToRightBottom:
            startPoint = CGPoint.init(x: 0, y: 0)
            endPoint = CGPoint.init(x: width, y: height)
        case .leftBottomToRightTop:
            startPoint = CGPoint.init(x: 0, y: height)
            endPoint = CGPoint.init(x: width, y: 0)
        case .rightTopToLeftBottom:
            startPoint = CGPoint.init(x: width, y: 0)
            endPoint = CGPoint.init(x: 0, y: height)
        case .RightBottomToLeftTop:
            startPoint = CGPoint.init(x: width, y: height)
            endPoint = CGPoint.init(x: 0, y: 0)
        }

        context.drawLinearGradient(gradient, start: startPoint, end: endPoint, options: .drawsBeforeStartLocation)
        let image = UIGraphicsGetImageFromCurrentImageContext()!
        context.restoreGState()
        UIGraphicsEndImageContext()

        return UIColor.init(patternImage: image)
    }

}

它与 UILabel 完美搭配,但是,标题在 UIButton 上消失了:

private lazy var gradientButton: GradientButton = {
    let gradientButton = GradientButton.init(colors: [UIColor.orange, UIColor.purple], direction: .leftToRight)
    gradientButton.setTitle("This is a Button", for: .normal)
    gradientButton.setTitleColor(.black, for: .normal)
    gradientButton.titleLabel?.font = UIFont.boldSystemFont(ofSize: 30)
    return gradientButton
}()

所以我想知道为什么标题消失了?

如何解决?

注意:我说的是颜色,所以不要告诉我添加图层或插入图层。

标签: swiftuibutton

解决方案


这是因为你的实现layoutSubviews是错误的。你永远不会打电话super,所以按钮永远不会真正布局。

让我们修复它:

override func layoutSubviews() {
    super.layoutSubviews()
    self.backgroundColor = UIColor.gradientColorWith(bounds: self.bounds, colors: self.colors, direction: self.direction)
}

让我们测试一下:

let b = self.gradientButton
b.sizeToFit()
b.frame.origin = CGPoint(x: 50, y: 50)
self.view.addSubview(b)

在此处输入图像描述


推荐阅读