Visual_Novel_iOS/crush/Crush/Src/Components/UI/Buttons/StyleButton.swift

363 lines
13 KiB
Swift
Raw Normal View History

2025-10-09 10:29:35 +00:00
//
// 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
}
}