swift - 当按钮的背景颜色为渐变时,标题消失了
问题描述
这是我的自定义按钮:
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
}()
所以我想知道为什么标题消失了?
如何解决?
注意:我说的是颜色,所以不要告诉我添加图层或插入图层。
解决方案
这是因为你的实现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)
推荐阅读
- visual-studio - 在 if 结构中定义时被视为未定义的变量
- flutter - Flutter 中的目标事件监听
- swift - SwiftUI 致命错误:未找到类型的 ObservableObject
- meteor - Meteor JS中的周围背景颜色
- feathersjs - 在羽毛 JS 中将文件发送到前端
- react-native - React-Native:所有选项卡上的抽屉导航器(react-navigation v5)
- reactjs - 获取必须渲染的错误文本组件
- python - PyQt5 QTreeView 显示父目录
- angular - Angular2 [selected] 不适用于 [ngValue]
- sql - 在 Python 中使用 SQL 移动平均线