项目为了更好的视觉呈现,可能会使用到渐变效果。若是一两处的话,可以让UI切下图,但很多时候还是得靠自己代码去弄
- 使用CAGradientLayer:
1.colors(CGColor)设置显示的颜色,
2.startPoint/endPoint(0.0~1.1)设置颜色起始/终点位置,左上角(0.0),右下角(1.1)
class myBtn:UIButton {
/// 渐变层
lazy var bgLayer: CAGradientLayer = {
let lay = CAGradientLayer()
lay.colors = [UIColor.black.cgColor, UIColor.green.cgColor]//设置颜色
lay.startPoint = CGPoint(x: 0.5, y: 1)//起始位置
lay.endPoint = CGPoint(x: 1, y: 0)//结束位置
return lay
}()
override init(frame: CGRect) {
super.init(frame: frame)
self.layer.insertSublayer(bgLayer, at: 0)//将渐变层添加到控件上
}
override func layoutSubviews() {
super.layoutSubviews()
//渐变层需要确定大小
self.bgLayer.frame = CGRect(x: 0, y: 0, width: self.frame.width, height: self.frame.height)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
主要内容就是上面这点
- 为了方便项目中的使用,我这里做了一个简单的封装,兼容深色模式的处理
需要主动监听手机模式的变化
-
extension Notification.Name { ///手机深色模式切换的通知 static let TraitCollectionDidChangeNotification = NSNotification.Name("TraitCollectionDidChangeNotification") }
对UIViewController使用交换方法(之前我写过一片文章中用过HZJSwizzlingProtocol)
// MARK: - 交换方法
extension UIViewController:HZJSwizzlingProtocol {
static func Swizzling() {
self.changeMethod(#selector(traitCollectionDidChange(_:)), selector2: #selector(hzj_traitCollectionDidChange(_:)))
}
/// 交换
static func changeMethod(_ selector1:Selector, selector2:Selector) {
guard let method1 = class_getInstanceMethod(self, selector1) else {return}
guard let method2 = class_getInstanceMethod(self, selector2) else {return}
if (class_addMethod(self, selector1, method_getImplementation(method2), method_getTypeEncoding(method2))) {
class_replaceMethod(self, selector2, method_getImplementation(method1), method_getTypeEncoding(method1))
} else {
method_exchangeImplementations(method1, method2)
}
}
/// 深色模式切换时,发送通知
/// - Parameter previousTraitCollection: <#previousTraitCollection description#>
@objc func hzj_traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
self.hzj_traitCollectionDidChange(previousTraitCollection)
NotificationCenter.default.post(name: .TraitCollectionDidChangeNotification, object: previousTraitCollection)
}
}
然后就是封装了
class HZJGradientLayer: CAGradientLayer {
private var _allColors:[UIColor] = []
/// 便于直接通过UIColor设置渐变色
var allColors:[UIColor]{
set{
self._allColors = newValue
self.colors = newValue.map{$0.cgColor}
}
get{
return _allColors
}
}
///当前的手机模式
private var layerType:UITraitCollection?{
didSet{
if self.layerType != oldValue {
self.colors = self.allColors.map{$0.cgColor}
}
}
}
///构造方法
init(_ colors:[UIColor] = [UIColor.black.withAlphaComponent(0.05),UIColor.green.withAlphaComponent(0.25)], start:CGPoint = CGPoint(x: 0.5, y: 0), end:CGPoint = CGPoint(x: 1, y: 1)) {
super.init()
if #available(iOS 13.0, *) {
self.layerType = .current
} else {
}
self.allColors = colors
self.startPoint = start
self.endPoint = end
//接收模式改变的通知
NotificationCenter.default.addObserver(self, selector: #selector(changeModel(_:)), name: .TraitCollectionDidChangeNotification, object: nil)
}
private override init() { super.init() }
private override init(layer: Any) { super.init(layer: layer) }
deinit {
NotificationCenter.default.removeObserver(self, name: .TraitCollectionDidChangeNotification, object: nil)
}
@objc func changeModel(_ noti:Notification) {
if let type = noti.object as? UITraitCollection{
self.layerType = type
}
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
用法和之前一样,只是颜色可以用过allColors直接用uicolor设置,而且支持深色模式了
来源:oschina
链接:https://my.oschina.net/wshzj/blog/4314163