iOS Cocoa Touch Framework 中的轻扫点击手势操作



我正在开发一个 Cocoa Touch Framework 或动态库,它将使用 Swift 捕获用户操作。

例如,当用户点击标签时,我的框架应该知道它。 为了实现此行为,我正在使用方法重排。

我正在为UITapGestureRecognizer创建一个扩展.在这个扩展中,initialize方法中,我正在滑动 init :

open override class func initialize() {
guard self === UITapGestureRecognizer.self else { return }
let originalSelector = #selector(self.init(target:action:))
let swizzledSelector = #selector(swizzled_init(target:action:))
swizzling(self, originalSelector, swizzledSelector)
}
func swizzled_init(target: Any, action: Selector) {
swizzled_init(target : target,action: action)
print("swizzled_init"+action.description)
//This part is for swizzling the the action which is being provided by the developer at the time of init.
guard self === UITapGestureRecognizer.self else { return }
let originalSelector = action
let swizzledSelector = #selector(swizzled_action(sender:))
swizzling(self.classForCoder, originalSelector, swizzledSelector)
}
func swizzled_action(sender : UITapGestureRecognizer? = nil){
print("swizzled_action"+(sender?.description)!)
} 

在旋转初始化后,点击实例在我的视图控制器中为零。

let tap = UITapGestureRecognizer.init(target: self, action: #selector(buttonTapped(sender:)))

第二个问题是swizzled_init方法中的这个:

guard self === UITapGestureRecognizer.self else { return }

正在失败。

你能指导我解决这些问题吗?

这对我来说很成功。我创建了一个能够处理各种类类型的SDK,包括我的UIGestureRecognizer实现。

import UIKit
extension UIGestureRecognizer {
static func swizzle() {
if let originalMethod = 
class_getInstanceMethod(UIGestureRecognizer.self, #selector(UIGestureRecognizer.init(target:action:))),
let swizzledMethod = class_getInstanceMethod(UIGestureRecognizer.self, #selector(UIGestureRecognizer.swizzled_init(target:action:))) {
method_exchangeImplementations(originalMethod, swizzledMethod)
}
}
private static var _myComputedProperty = [String:Any]()
private var targetProperty:AnyObject? {
get {
let tmpAddress = String(format: "%ptargetProperty", unsafeBitCast(self, to: Int.self))
return UIGestureRecognizer._myComputedProperty[tmpAddress] as AnyObject
}
set(newValue) {
let tmpAddress = String(format: "%ptargetProperty", unsafeBitCast(self, to: Int.self))
UIGestureRecognizer._myComputedProperty[tmpAddress] = newValue
}
}
private var actionProperty:Selector? {
get {
let tmpAddress = String(format: "%pactionProperty", unsafeBitCast(self, to: Int.self))
return UIGestureRecognizer._myComputedProperty[tmpAddress] as? Selector
}
set(newValue) {
let tmpAddress = String(format: "%pactionProperty", unsafeBitCast(self, to: Int.self))
UIGestureRecognizer._myComputedProperty[tmpAddress] = newValue
}
}
@discardableResult @objc func swizzled_init(target: AnyObject?, action: Selector?) -> Selector {
targetProperty = target
actionProperty = action
return swizzled_init(target: self, action:  #selector(swizzled_action))
}
@objc dynamic func swizzled_action() {
guard let targetProperty = targetProperty, let actionProperty = actionProperty else { return }
targetProperty.performSelector(onMainThread: actionProperty, with: self, waitUntilDone: false)
NotificationCenter.default.post(name: NSNotification.Name("trackEvent"), object: nil, userInfo: ["event": "interacted with on: (self.description)"])
}

}

编辑:

请添加可控手势,因为系统手势无法通过此功能进行管理。

任何需要处理的目标都必须扩展 TrackbleGesture。

import UIKit
public protocol TrackbleGesture: AnyObject {}
extension UIGestureRecognizer {
static func swizzle() {
if let originalMethod = class_getInstanceMethod(UIGestureRecognizer.self, #selector(UIGestureRecognizer.init(target:action:))),
let swizzledMethod = class_getInstanceMethod(UIGestureRecognizer.self, #selector(UIGestureRecognizer.swizzled_init(target:action:))) {
method_exchangeImplementations(originalMethod, swizzledMethod)
}
}
private static var _myComputedProperty = [String:Any]()
private var targetProperty:AnyObject? {
get {
let tmpAddress = String(format: "%p-targetProperty", unsafeBitCast(self, to: Int.self))
return UIGestureRecognizer._myComputedProperty[tmpAddress] as AnyObject
}
set(newValue) {
let tmpAddress = String(format: "%p-targetProperty", unsafeBitCast(self, to: Int.self))
UIGestureRecognizer._myComputedProperty[tmpAddress] = newValue
}
}
private var actionProperty:Selector? {
get {
let tmpAddress = String(format: "%p-actionProperty", unsafeBitCast(self, to: Int.self))
return UIGestureRecognizer._myComputedProperty[tmpAddress] as? Selector
}
set(newValue) {
let tmpAddress = String(format: "%p-actionProperty", unsafeBitCast(self, to: Int.self))
UIGestureRecognizer._myComputedProperty[tmpAddress] = newValue
}
}
@discardableResult @objc func swizzled_init(target: AnyObject?, action: Selector?) -> Selector {
guard target is TrackbleGesture else { return swizzled_init(target: target, action: action) }
targetProperty = target
actionProperty = action
return swizzled_init(target: self, action:  #selector(swizzled_action))
}
@objc dynamic func swizzled_action() {
guard let targetProperty = targetProperty, let actionProperty = actionProperty else { return }
targetProperty.performSelector(onMainThread: actionProperty, with: self, waitUntilDone: false)
NotificationCenter.default.post(name: NSNotification.Name("trackEvent"), object: nil, userInfo: ["event": "interacted with: (self.description)"])
}

}

以保留 UIGestureRecognizer 的正确状态

更改此行:

targetProperty.performSelector(onMainThread: actionProperty, with: self, waitUntilDone: false)

自:

targetProperty.performSelector(onMainThread: actionProperty, with: self, waitUntilDone: true)

最新更新