363 lines
13 KiB
Swift
363 lines
13 KiB
Swift
//
|
|
// StyleButton.swift
|
|
// Crush
|
|
//
|
|
// Created by Leon on 2025/7/17.
|
|
//
|
|
|
|
import SwiftyAttributes
|
|
import UIKit
|
|
|
|
enum StyleButtonSize {
|
|
/// height: 32, tls
|
|
case small
|
|
/// height: 40, tlm
|
|
case medium
|
|
/// height: 48, tll
|
|
case large
|
|
}
|
|
|
|
class StyleButton: CLButton {
|
|
var radius: CGFloat = 0
|
|
private var enableBorderColor: UIColor?
|
|
private var disableBorderColor: UIColor?
|
|
private var pressBorderColor: UIColor?
|
|
|
|
var text: String? {
|
|
didSet {
|
|
setTitle(text, for: .normal)
|
|
}
|
|
}
|
|
|
|
var titleColor: UIColor? {
|
|
didSet {
|
|
setTitleColor(titleColor, for: .normal)
|
|
}
|
|
}
|
|
|
|
override var isEnabled: Bool {
|
|
didSet {
|
|
if let enableColor = enableBorderColor, let disableColor = disableBorderColor {
|
|
layer.borderColor = isEnabled ? enableColor.cgColor : disableColor.cgColor
|
|
}
|
|
}
|
|
}
|
|
|
|
override var isHighlighted: Bool {
|
|
didSet {
|
|
if let enableColor = enableBorderColor, let pressColor = pressBorderColor {
|
|
layer.borderColor = isHighlighted ? pressColor.cgColor : enableColor.cgColor
|
|
}
|
|
}
|
|
}
|
|
|
|
override init(frame: CGRect) {
|
|
super.init(frame: frame)
|
|
|
|
backgroundColor = nil
|
|
tintColor = nil
|
|
contentMode = .scaleAspectFill
|
|
titleLabel?.setContentHuggingPriority(UILayoutPriority(248), for: .horizontal)
|
|
//setContentHuggingPriority(UILayoutPriority(248), for: .horizontal)
|
|
setContentCompressionResistancePriority(UILayoutPriority(755), for: .horizontal)
|
|
titleLabel?.adjustsFontSizeToFitWidth = true
|
|
|
|
constraints.forEach {
|
|
if $0.firstAttribute == .height {
|
|
removeConstraint($0)
|
|
}
|
|
}
|
|
}
|
|
|
|
required init?(coder: NSCoder) {
|
|
fatalError("init(coder:) has not been implemented")
|
|
}
|
|
|
|
// MARK: - Style Buttons
|
|
public func primary(size: StyleButtonSize) {
|
|
setTitleColor(.c.ctpn, for: .normal)
|
|
setTitleColor(.c.ctpd, for: .disabled)
|
|
setTitleColor(.c.ctpn, for: .highlighted)
|
|
|
|
// var configuration = UIButton.Configuration.plain()
|
|
// configuration.contentInsets = NSDirectionalEdgeInsets(top: 0, leading: 32, bottom: 0, trailing: 32)
|
|
// self.configuration = configuration
|
|
|
|
// 设置状态更新处理
|
|
// configurationUpdateHandler = { [weak self] button in
|
|
// guard self != nil else { return }
|
|
// var updatedConfig = button.configuration ?? UIButton.Configuration.plain()
|
|
//
|
|
// // 根据按钮状态设置不同的背景图片
|
|
// switch button.state {
|
|
// case .normal:
|
|
// let gradient = CLSystemToken.gradient(token: .cpgn)
|
|
// let normalBg = gradient.toImage(size: .init(width: 40, height: 10))
|
|
// updatedConfig.background.image = normalBg
|
|
// updatedConfig.background.imageContentMode = .scaleAspectFill
|
|
// case .highlighted:
|
|
// let highlight = CLSystemToken.gradient(token: .cpgp)
|
|
// let pressBg = highlight.toImage(size: .init(width: 40, height: 10))
|
|
// updatedConfig.background.image = pressBg
|
|
// updatedConfig.background.imageContentMode = .scaleAspectFill
|
|
// case .disabled:
|
|
// let disabledImage = UIImage.withColor(color: .c.cpd, size: .init(width: 20, height: 20))
|
|
// updatedConfig.background.image = disabledImage
|
|
// updatedConfig.background.imageContentMode = .scaleAspectFill
|
|
// default:
|
|
// let gradient = CLSystemToken.gradient(token: .cpgn)
|
|
// let normalBg = gradient.toImage(size: .init(width: 40, height: 10))
|
|
// updatedConfig.background.image = normalBg
|
|
// }
|
|
//
|
|
// button.configuration = updatedConfig
|
|
// }
|
|
|
|
let gradient = CLSystemToken.gradient(token: .cpgn)
|
|
let normalBg = gradient.toImage(size: .init(width: 40, height: 10))
|
|
setBackgroundImage(normalBg, for: .normal)
|
|
|
|
let highlight = CLSystemToken.gradient(token: .cpgp)
|
|
let pressBg = highlight.toImage(size: .init(width: 40, height: 10))
|
|
setBackgroundImage(pressBg, for: .highlighted)
|
|
|
|
let disabledImage = UIImage.withColor(color: .c.cpd, size: .init(width: 20, height: 20))
|
|
setBackgroundImage(disabledImage, for: .disabled)
|
|
|
|
commonDealSize(size: size)
|
|
commonDealSpacing(size: size)
|
|
|
|
layoutIfNeeded()
|
|
}
|
|
|
|
public func tertiary(size: StyleButtonSize) {
|
|
setTitleColor(.c.ctpn, for: .normal)
|
|
setTitleColor(.c.ctpd, for: .disabled)
|
|
setTitleColor(.c.ctpn, for: .highlighted)
|
|
|
|
let normalBg = UIImage.withColor(color: .c.csen, size: .init(width: 10, height: 10))
|
|
setBackgroundImage(normalBg, for: .normal)
|
|
let pressBg = UIImage.withColor(color: .c.csep, size: .init(width: 10, height: 10))
|
|
setBackgroundImage(pressBg, for: .highlighted)
|
|
let disabledImage = UIImage.withColor(color: .c.csed, size: .init(width: 10, height: 10))
|
|
setBackgroundImage(disabledImage, for: .disabled)
|
|
|
|
commonDealSize(size: size)
|
|
commonDealSpacing(size: size)
|
|
|
|
setNeedsDisplay()
|
|
layoutIfNeeded()
|
|
}
|
|
|
|
public func defaultSecondary(size: StyleButtonSize) {
|
|
setTitleColor(.c.cpvn, for: .normal)
|
|
setTitleColor(.c.ctd, for: .disabled)
|
|
setTitleColor(.c.cpvp, for: .highlighted)
|
|
|
|
enableBorderColor = .c.cpvn
|
|
disableBorderColor = .c.cpvd
|
|
pressBorderColor = .c.cpvp
|
|
|
|
layer.borderWidth = CLSystemToken.border(token: .bs)
|
|
isEnabled = true
|
|
radius = CLSystemToken.radius(token: .rp)
|
|
|
|
commonDealSize(size: size)
|
|
commonDealSpacing(size: size)
|
|
|
|
layoutIfNeeded()
|
|
}
|
|
|
|
public func defaultDestructive(size: StyleButtonSize) {
|
|
setTitleColor(.c.ctpn, for: .normal)
|
|
setTitleColor(.c.ctpd, for: .disabled)
|
|
setTitleColor(.c.ctpn, for: .highlighted)
|
|
|
|
// iOS 15+设置方法
|
|
// var configuration = UIButton.Configuration.plain()
|
|
// configuration.contentInsets = NSDirectionalEdgeInsets(top: 0, leading: 32, bottom: 0, trailing: 32)
|
|
// self.configuration = configuration
|
|
//
|
|
// // 设置状态更新处理
|
|
// configurationUpdateHandler = { [weak self] button in
|
|
// guard self != nil else { return }
|
|
// var updatedConfig = button.configuration ?? UIButton.Configuration.plain()
|
|
//
|
|
// // 根据按钮状态设置不同的背景图片
|
|
// switch button.state {
|
|
// case .normal:
|
|
// let normalBg = UIImage.withColor(color: .c.cin, size: .init(width: 10, height: 10))
|
|
// updatedConfig.background.image = normalBg
|
|
// updatedConfig.background.imageContentMode = .scaleAspectFill
|
|
// case .highlighted:
|
|
// let pressBg = UIImage.withColor(color: .c.cip, size: .init(width: 10, height: 10))
|
|
// updatedConfig.background.image = pressBg
|
|
// updatedConfig.background.imageContentMode = .scaleAspectFill
|
|
// case .disabled:
|
|
// let disabledImage = UIImage.withColor(color: .c.cid, size: .init(width: 10, height: 10))
|
|
// updatedConfig.background.image = disabledImage
|
|
// updatedConfig.background.imageContentMode = .scaleAspectFill
|
|
// default:
|
|
// let gradient = CLSystemToken.gradient(token: .cin)
|
|
// let normalBg = gradient.toImage(size: .init(width: 40, height: 10))
|
|
// updatedConfig.background.image = normalBg
|
|
// }
|
|
//
|
|
// button.configuration = updatedConfig
|
|
// }
|
|
let normalBg = UIImage.withColor(color: .c.cin, size: .init(width: 10, height: 10))
|
|
setBackgroundImage(normalBg, for: .normal)
|
|
|
|
let pressBg = UIImage.withColor(color: .c.cip, size: .init(width: 10, height: 10))
|
|
setBackgroundImage(pressBg, for: .highlighted)
|
|
|
|
let disabledImage = UIImage.withColor(color: .c.cid, size: .init(width: 10, height: 10))
|
|
setBackgroundImage(disabledImage, for: .disabled)
|
|
|
|
commonDealSize(size: size)
|
|
commonDealSpacing(size: size)
|
|
layoutIfNeeded()
|
|
}
|
|
|
|
/// 渐变主题色 button
|
|
public func context(size: StyleButtonSize) {
|
|
setTitleColor(.c.csbn, for: .normal)
|
|
setTitleColor(.c.ctpd, for: .disabled)
|
|
setTitleColor(.c.csbp, for: .highlighted)
|
|
|
|
// let c = UIColor.c.ccvn
|
|
let gradient = CLSystemToken.gradient(token: .ccvn)
|
|
let normalBg = gradient.toImage(size: CGSize(width: 40, height: 10))
|
|
setBackgroundImage(normalBg, for: .normal)
|
|
|
|
commonDealSize(size: size)
|
|
commonDealSpacing(size: size)
|
|
|
|
layoutIfNeeded()
|
|
}
|
|
|
|
public func vip(size: StyleButtonSize){
|
|
setTitleColor(.c.csbn, for: .normal)
|
|
setTitleColor(.c.ctpd, for: .disabled)
|
|
setTitleColor(.c.csbp, for: .highlighted)
|
|
|
|
let gradient = CLSystemToken.gradient(token: .ccvn)
|
|
let normalBg = gradient.toImage(size: CGSize(width: 40, height: 10))
|
|
setBackgroundImage(normalBg, for: .normal)
|
|
|
|
commonDealSize(size: size)
|
|
commonDealSpacing(size: size)
|
|
|
|
layoutIfNeeded()
|
|
}
|
|
|
|
public func text(size: StyleButtonSize){
|
|
setTitleColor(.c.cpvn, for: .normal)
|
|
setTitleColor(.c.ctd, for: .disabled)
|
|
setTitleColor(.c.cpvp, for: .highlighted)
|
|
|
|
setBackgroundImage(nil, for: .normal)
|
|
|
|
commonDealSize(size: size)
|
|
commonDealSpacing(size: size)
|
|
|
|
layoutIfNeeded()
|
|
}
|
|
|
|
public func contrastTertiaryLight(size: StyleButtonSize){
|
|
setTitleColor(.c.ctpn, for: .normal)
|
|
setTitleColor(.c.ctpd, for: .disabled)
|
|
setTitleColor(.c.ctpn, for: .highlighted)
|
|
|
|
let normalBg = UIImage.withColor(color: .c.cseln, size: .init(width: 10, height: 10))
|
|
setBackgroundImage(normalBg, for: .normal)
|
|
let pressBg = UIImage.withColor(color: .c.cselp, size: .init(width: 10, height: 10))
|
|
setBackgroundImage(pressBg, for: .highlighted)
|
|
let disabledImage = UIImage.withColor(color: .c.cseld, size: .init(width: 10, height: 10))
|
|
setBackgroundImage(disabledImage, for: .disabled)
|
|
|
|
commonDealSize(size: size)
|
|
commonDealSpacing(size: size)
|
|
|
|
setNeedsDisplay()
|
|
layoutIfNeeded()
|
|
}
|
|
|
|
public func contrastTertiaryDark(size: StyleButtonSize){
|
|
setTitleColor(.c.ctpn, for: .normal)
|
|
setTitleColor(.c.ctpd, for: .disabled)
|
|
setTitleColor(.c.ctpn, for: .highlighted)
|
|
|
|
let normalBg = UIImage.withColor(color: .c.csedn, size: .init(width: 10, height: 10))
|
|
setBackgroundImage(normalBg, for: .normal)
|
|
let pressBg = UIImage.withColor(color: .c.csedp, size: .init(width: 10, height: 10))
|
|
setBackgroundImage(pressBg, for: .highlighted)
|
|
let disabledImage = UIImage.withColor(color: .c.csedd, size: .init(width: 10, height: 10))
|
|
setBackgroundImage(disabledImage, for: .disabled)
|
|
|
|
commonDealSize(size: size)
|
|
commonDealSpacing(size: size)
|
|
|
|
setNeedsDisplay()
|
|
layoutIfNeeded()
|
|
}
|
|
|
|
|
|
// MARK: - Common
|
|
|
|
private func commonDealSize(size: StyleButtonSize) {
|
|
switch size {
|
|
case .small:
|
|
let typography = CLSystemToken.typography(token: .tls)
|
|
titleLabel?.font = typography.font
|
|
snp.makeConstraints { make in
|
|
make.height.equalTo(32)
|
|
}
|
|
case .medium:
|
|
let typography = CLSystemToken.typography(token: .tlm)
|
|
titleLabel?.font = typography.font
|
|
snp.makeConstraints { make in
|
|
make.height.equalTo(40)
|
|
}
|
|
case .large:
|
|
let typography = CLSystemToken.typography(token: .tll)
|
|
titleLabel?.font = typography.font
|
|
snp.makeConstraints { make in
|
|
make.height.equalTo(48)
|
|
}
|
|
}
|
|
}
|
|
|
|
private func commonDealSpacing(size: StyleButtonSize) {
|
|
switch size {
|
|
case .small:
|
|
contentEdgeInsets = UIEdgeInsets(top: 0, left: 16, bottom: 0, right: 16)
|
|
// var configuration = self.configuration ?? UIButton.Configuration.plain()
|
|
// configuration.contentInsets = NSDirectionalEdgeInsets(top: 0, leading: 16, bottom: 0, trailing: 16)
|
|
// self.configuration = configuration
|
|
case .medium:
|
|
contentEdgeInsets = UIEdgeInsets(top: 0, left: 20, bottom: 0, right: 20)
|
|
// var configuration = self.configuration ?? UIButton.Configuration.plain()
|
|
// configuration.contentInsets = NSDirectionalEdgeInsets(top: 0, leading: 20, bottom: 0, trailing: 20)
|
|
// self.configuration = configuration
|
|
case .large:
|
|
contentEdgeInsets = UIEdgeInsets(top: 0, left: 32, bottom: 0, right: 32)
|
|
// var configuration = self.configuration ?? UIButton.Configuration.plain()
|
|
// configuration.contentInsets = NSDirectionalEdgeInsets(top: 0, leading: 32, bottom: 0, trailing: 32)
|
|
// self.configuration = configuration
|
|
}
|
|
}
|
|
|
|
// MARK: layout
|
|
|
|
override func layoutSubviews() {
|
|
super.layoutSubviews()
|
|
if radius >= 1 {
|
|
layer.cornerRadius = radius
|
|
} else {
|
|
layer.cornerRadius = bounds.size.height * 0.5
|
|
}
|
|
layer.masksToBounds = true
|
|
}
|
|
}
|