|
| 1 | +// |
| 2 | +// UIControl+EnableSendActionsForControlEvents.swift |
| 3 | +// Rex |
| 4 | +// |
| 5 | +// Created by David Rodrigues on 24/04/16. |
| 6 | +// Copyright © 2016 Neil Pankey. All rights reserved. |
| 7 | +// |
| 8 | + |
| 9 | +import UIKit |
| 10 | + |
| 11 | +/// Unfortunately, there's an apparent limitation in using `sendActionsForControlEvents` |
| 12 | +/// on unit-tests for any control besides `UIButton` which is very unfortunate since we |
| 13 | +/// want test our bindings for `UIDatePicker`, `UISwitch`, `UITextField` and others |
| 14 | +/// in the future. To be able to test them, we're now using swizzling to manually invoke |
| 15 | +/// the pair target+action. |
| 16 | +extension UIControl { |
| 17 | + |
| 18 | + public override class func initialize() { |
| 19 | + |
| 20 | + struct Static { |
| 21 | + static var token: dispatch_once_t = 0 |
| 22 | + } |
| 23 | + |
| 24 | + if self !== UIControl.self { |
| 25 | + return |
| 26 | + } |
| 27 | + |
| 28 | + dispatch_once(&Static.token) { |
| 29 | + |
| 30 | + let originalSelector = #selector(UIControl.sendAction(_:to:forEvent:)) |
| 31 | + let swizzledSelector = #selector(UIControl.rex_sendAction(_:to:forEvent:)) |
| 32 | + |
| 33 | + let originalMethod = class_getInstanceMethod(self, originalSelector) |
| 34 | + let swizzledMethod = class_getInstanceMethod(self, swizzledSelector) |
| 35 | + |
| 36 | + let didAddMethod = class_addMethod(self, |
| 37 | + originalSelector, |
| 38 | + method_getImplementation(swizzledMethod), |
| 39 | + method_getTypeEncoding(swizzledMethod)) |
| 40 | + |
| 41 | + if didAddMethod { |
| 42 | + class_replaceMethod(self, |
| 43 | + swizzledSelector, |
| 44 | + method_getImplementation(originalMethod), |
| 45 | + method_getTypeEncoding(originalMethod)) |
| 46 | + } else { |
| 47 | + method_exchangeImplementations(originalMethod, swizzledMethod) |
| 48 | + } |
| 49 | + } |
| 50 | + } |
| 51 | + |
| 52 | + // MARK: - Method Swizzling |
| 53 | + |
| 54 | + func rex_sendAction(action: Selector, to target: AnyObject?, forEvent event: UIEvent?) { |
| 55 | + target?.performSelector(action, withObject: self) |
| 56 | + } |
| 57 | +} |
0 commit comments