87 lines
3.1 KiB
Swift
87 lines
3.1 KiB
Swift
//
|
||
// UIButtonExt.swift
|
||
// Crush
|
||
//
|
||
// Created by Leon on 2025/7/18.
|
||
//
|
||
|
||
extension UIButton {
|
||
// 使用 associated object 存储点击范围的内边距
|
||
private struct AssociatedKeys {
|
||
static var touchAreaInsets = "touchAreaInsets"
|
||
}
|
||
|
||
// 可动态设置的点击范围内边距
|
||
@objc var touchAreaInsets: UIEdgeInsets {
|
||
get {
|
||
return objc_getAssociatedObject(self, &AssociatedKeys.touchAreaInsets) as? UIEdgeInsets ?? .zero
|
||
}
|
||
set {
|
||
objc_setAssociatedObject(self, &AssociatedKeys.touchAreaInsets, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
|
||
}
|
||
}
|
||
|
||
// 重写 point(inside:with:) 方法,扩展点击范围
|
||
override open func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
|
||
let insets = touchAreaInsets
|
||
// 扩展后的点击区域
|
||
let extendedBounds = bounds.inset(by: UIEdgeInsets(
|
||
top: -insets.top,
|
||
left: -insets.left,
|
||
bottom: -insets.bottom,
|
||
right: -insets.right
|
||
))
|
||
return extendedBounds.contains(point)
|
||
}
|
||
}
|
||
|
||
// 全局防抖影响一些基本的barButton的点击事件,和一些三方库冲突
|
||
//import ObjectiveC.runtime
|
||
//
|
||
//extension UIControl {
|
||
// private struct AssociatedKeys {
|
||
// static var ignoreEvent = 0
|
||
// static var clickInterval = 0
|
||
// }
|
||
//
|
||
// /// 是否正在忽略点击事件
|
||
// private var isIgnoringEvent: Bool {
|
||
// get { (objc_getAssociatedObject(self, &AssociatedKeys.ignoreEvent) as? Bool) ?? false }
|
||
// set { objc_setAssociatedObject(self, &AssociatedKeys.ignoreEvent, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) }
|
||
// }
|
||
//
|
||
// /// 点击间隔,默认 0.8 秒
|
||
// var clickInterval: TimeInterval {
|
||
// get { (objc_getAssociatedObject(self, &AssociatedKeys.clickInterval) as? TimeInterval) ?? 0.8 }
|
||
// set { objc_setAssociatedObject(self, &AssociatedKeys.clickInterval, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) }
|
||
// }
|
||
//
|
||
// // MARK: - 启用防抖(全局一次即可)
|
||
// public static func enableClickDebounce() {
|
||
// let originalSelector = #selector(UIControl.sendAction(_:to:for:))
|
||
// let swizzledSelector = #selector(UIControl.swizzled_sendAction(_:to:for:))
|
||
//
|
||
// guard let originalMethod = class_getInstanceMethod(UIControl.self, originalSelector),
|
||
// let swizzledMethod = class_getInstanceMethod(UIControl.self, swizzledSelector) else {
|
||
// return
|
||
// }
|
||
// method_exchangeImplementations(originalMethod, swizzledMethod)
|
||
// }
|
||
//
|
||
// @objc private func swizzled_sendAction(_ action: Selector, to target: Any?, for event: UIEvent?) {
|
||
// if isIgnoringEvent {
|
||
// return
|
||
// }
|
||
//
|
||
// if clickInterval > 0 {
|
||
// isIgnoringEvent = true
|
||
// DispatchQueue.main.asyncAfter(deadline: .now() + clickInterval) { [weak self] in
|
||
// self?.isIgnoringEvent = false
|
||
// }
|
||
// }
|
||
//
|
||
// // 调用原始实现
|
||
// swizzled_sendAction(action, to: target, for: event)
|
||
// }
|
||
//}
|