UIButton+Ex.swift 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. //
  2. // UIButton+Ex.swift
  3. // TSLiveWallpaper
  4. //
  5. // Created by 100Years on 2024/12/20.
  6. //
  7. public extension UIButton {
  8. private struct AssociatedKeys {
  9. static var actionKey = "UIButtonActionKey"
  10. }
  11. // 存储回调闭包
  12. private var actionClosure: (() -> Void)? {
  13. get {
  14. return objc_getAssociatedObject(self, &AssociatedKeys.actionKey) as? (() -> Void)
  15. }
  16. set {
  17. objc_setAssociatedObject(self, &AssociatedKeys.actionKey, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
  18. }
  19. }
  20. /// 快速创建 UIButton
  21. /// - Parameters:
  22. /// - title: 按钮的标题
  23. /// - image: 按钮的图标
  24. /// - backgroundImage: 按钮的背景图
  25. /// - backgroundColor: 按钮的背景色
  26. /// - font: 按钮的字体
  27. /// - titleColor: 按钮的字体颜色
  28. /// - action: 按钮点击事件的回调
  29. static func createButton(title: String? = nil,
  30. image: UIImage? = nil,
  31. backgroundImage: UIImage? = nil,
  32. backgroundColor: UIColor? = nil,
  33. font: UIFont? = nil,
  34. titleColor: UIColor? = nil,
  35. corner:CGFloat = 0,
  36. autoMirrored: Bool = true,
  37. action: (() -> Void)? = nil) -> UIButton {
  38. let button = UIButton(type: .custom)
  39. button.setUpButton(title: title,
  40. image: image,
  41. backgroundImage: backgroundImage,
  42. backgroundColor: backgroundColor,
  43. font: font,
  44. titleColor: titleColor,
  45. corner:corner,
  46. autoMirrored: autoMirrored,
  47. action: action)
  48. return button
  49. }
  50. func setUpButton(title: String? = nil,
  51. image: UIImage? = nil,
  52. backgroundImage: UIImage? = nil,
  53. backgroundColor: UIColor? = nil,
  54. font: UIFont? = nil,
  55. titleColor: UIColor? = nil,
  56. corner:CGFloat = 0,
  57. autoMirrored: Bool = true,
  58. action: (() -> Void)? = nil){
  59. let button = self
  60. button.showsTouchWhenHighlighted = false
  61. button.adjustsImageWhenHighlighted = false
  62. // 设置标题
  63. if let title = title {
  64. button.setTitle(title, for: .normal)
  65. }
  66. // 设置图片
  67. if let image = image {
  68. if autoMirrored {
  69. button.setImage(image.mirrored, for: .normal)
  70. }else{
  71. button.setImage(image, for: .normal)
  72. }
  73. }
  74. // 设置背景图片
  75. if let backgroundImage = backgroundImage {
  76. if autoMirrored {
  77. button.setBackgroundImage(backgroundImage.mirrored, for: .normal)
  78. }else{
  79. button.setBackgroundImage(backgroundImage, for: .normal)
  80. }
  81. }
  82. // 设置背景色
  83. if let backgroundColor = backgroundColor {
  84. button.backgroundColor = backgroundColor
  85. }
  86. // 设置字体
  87. if let font = font {
  88. button.titleLabel?.font = font
  89. }
  90. // 设置字体颜色
  91. if let titleColor = titleColor {
  92. button.setTitleColor(titleColor, for: .normal)
  93. }
  94. if corner > 0 {
  95. button.cornerRadius = corner
  96. }
  97. if let action = action {
  98. button.actionClosure = action
  99. button.addTarget(button, action: #selector(buttonTapped), for: .touchUpInside)
  100. }
  101. }
  102. // 按钮点击事件
  103. @objc private func buttonTapped() {
  104. actionClosure?()
  105. }
  106. public func preventMultipleTaps(delay: Double = 0.75) {
  107. self.isEnabled = false
  108. DispatchQueue.main.asyncAfter(deadline: .now() + delay) {
  109. self.isEnabled = true
  110. }
  111. }
  112. }
  113. public extension UIButton {
  114. public func setContentImageSpace(spacing:CGFloat = 4){
  115. if kIsRTL {
  116. contentEdgeInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: spacing) // 只调整 title 的 left
  117. imageEdgeInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: -spacing) // 只调整 image 的 right
  118. }else{
  119. contentEdgeInsets = UIEdgeInsets(top: 0, left: spacing, bottom: 0, right: 0) // 只调整 title 的 left
  120. imageEdgeInsets = UIEdgeInsets(top: 0, left: -spacing, bottom: 0, right: 0) // 只调整 image 的 right
  121. }
  122. }
  123. public func setTitleImageSpace(spacing:CGFloat = 4){
  124. if kIsRTL {
  125. titleEdgeInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: spacing) // 只调整 title 的 left
  126. imageEdgeInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: -spacing) // 只调整 image 的 right
  127. }else{
  128. titleEdgeInsets = UIEdgeInsets(top: 0, left: spacing, bottom: 0, right: 0) // 只调整 title 的 left
  129. imageEdgeInsets = UIEdgeInsets(top: 0, left: -spacing, bottom: 0, right: 0) // 只调整 image 的 right
  130. }
  131. }
  132. }
  133. public class TSUIExpandedTouchButton: UIButton {
  134. public var indexPath: IndexPath = IndexPath(item: 0, section: 0)
  135. override public func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
  136. let buttonBounds = self.bounds
  137. let widthDelta = self.width * 0.5 // 增加点击区域的比例,这里增加了50%
  138. let heightDelta = self.height * 0.5
  139. let expandedBounds = buttonBounds.insetBy(dx: -widthDelta, dy: -heightDelta)
  140. return expandedBounds.contains(point)
  141. }
  142. }
  143. public class TSVerticalButton: UIButton {
  144. var spacing: CGFloat = 4 {
  145. didSet { setNeedsLayout() }
  146. }
  147. public override func layoutSubviews() {
  148. super.layoutSubviews()
  149. guard let imageView = imageView, let titleLabel = titleLabel else { return }
  150. // 图片居中靠上
  151. imageView.frame.origin.y = (bounds.height - imageView.frame.height - titleLabel.frame.height - spacing) / 2
  152. imageView.center.x = bounds.width / 2
  153. // 文字居中靠下
  154. titleLabel.frame.origin.y = imageView.frame.maxY + spacing
  155. titleLabel.center.x = bounds.width / 2
  156. }
  157. }