1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
| import UIKit
class GHUITapGestureRecognizerAction: NSObject { weak var target: UIResponder? var action: Selector? @objc func ghGestureRecognizerAction(sender: UIGestureRecognizer?) -> Void { if self.target == nil { return } if self.action == nil { return } UITapGestureRecognizerTrack.shared.trackGRAction(sender as? UITapGestureRecognizer, action: self.action!, target: self.target) if ((target?.responds(to: action)) == true) { target?.perform(action, with: sender) } } }
var ghGestureActionsKey: String = "GHGestureActionsKey"
extension UIResponder { var ghGestureActions: Array<GHUITapGestureRecognizerAction>? { set { objc_setAssociatedObject(self, &ghGestureActionsKey, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN) } get { return objc_getAssociatedObject(self, &ghGestureActionsKey) as? Array<GHUITapGestureRecognizerAction> } } }
private func swizzle(_ gesture: UITapGestureRecognizer.Type) { let selectors: Array<Array<Selector>> = [ [ #selector(UITapGestureRecognizer.init(target:action:)), #selector(gesture.gh_init(target:action:)) ], [ #selector(gesture.addTarget(_:action:)), #selector(gesture.gh_addTarget(_:action:)) ], ] for item in selectors { let originalSelector: Selector = item[0] let swizzledSelector: Selector = item[1] let originalMethod: Method? = class_getInstanceMethod(gesture, originalSelector) let swizzledMethod: Method? = class_getInstanceMethod(gesture, swizzledSelector) if originalMethod == nil { continue } let didAddMethod: Bool = class_addMethod(gesture, originalSelector, method_getImplementation(swizzledMethod!), method_getTypeEncoding(swizzledMethod!)) if didAddMethod { class_replaceMethod(gesture, swizzledSelector, method_getImplementation(originalMethod!), method_getTypeEncoding(originalMethod!)) } else { method_exchangeImplementations(originalMethod!, swizzledMethod!) } } }
extension UITapGestureRecognizer { private static let dispatchOnceTime: Void = { swizzle(UITapGestureRecognizer.self) }() @objc open class func startAOP() { guard self === UITapGestureRecognizer.self else { return } UITapGestureRecognizer.dispatchOnceTime } @objc func gh_init(target: Any?, action: Selector?) -> UIGestureRecognizer { if target == nil { return self.gh_init(target: target, action: action); } if (target as? UIResponder) == nil { return self.gh_init(target: target, action: action); } if (target as? UIResponder)?.ghGestureActions == nil { (target as? UIResponder)?.ghGestureActions = [] } let ghAction = GHUITapGestureRecognizerAction() ghAction.target = (target as? UIResponder) ghAction.action = action (target as? UIResponder)?.ghGestureActions?.append(ghAction) return self.gh_init(target: ghAction, action: #selector(ghAction.ghGestureRecognizerAction(sender:))) } @objc func gh_addTarget(_ target: Any, action: Selector) { if (target as? UIResponder) == nil { return self.gh_addTarget(target, action: action); } if (target as? UIResponder)?.ghGestureActions == nil { (target as? UIResponder)?.ghGestureActions = [] } let ghAction = GHUITapGestureRecognizerAction() ghAction.target = (target as? UIResponder) ghAction.action = action (target as? UIResponder)?.ghGestureActions?.append(ghAction) return self.gh_addTarget(ghAction, action: #selector(ghAction.ghGestureRecognizerAction(sender:))) } }
|