Skip to content

Instantly share code, notes, and snippets.

@swain
Created June 29, 2018 20:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save swain/4f75653d843a90aecd38dc096c8a955b to your computer and use it in GitHub Desktop.
Save swain/4f75653d843a90aecd38dc096c8a955b to your computer and use it in GitHub Desktop.
//
// UIControl+TargetAction.swift
//
// Created by Swain Molster on 6/26/18.
// Copyright © 2018 Swain Molster. All rights reserved.
//
import Foundation
/**
This class is used exclusively by `UIControl:addAction(controlEvents:action:)`, for the purpose of housing "action" closures.
*/
fileprivate class TargetAction: NSObject {
private let action: () -> Void
fileprivate init(action: @escaping () -> Void) {
self.action = action
}
@objc internal func executeAction() {
self.action()
}
}
extension UIControl {
/**
Sets a provided `action` closure to be performed for `controlEvents`. _IMPORTANT_: The return value of this function must be retained for as long as the `action` should still be triggered.
- Parameters:
- controlEvents: The `UIControlEvents` that should trigger the provided `action`.
- action: A closure to be executed whenever the provided `UIControlEvents` occur.
- Returns: An object that must be retained for the entire desired lifetime of the action association.
_Discussion_
The return value of this function must be retained for the desired lifetime of the action.
For example, this will NOT work:
```
func addActionToButton(button: UIButton) {
button.addAction(for: .touchUpInside) {
print("Button Pressed") // This will never be executed, since the returned token wasn't stored.
}
}
```
Rather, this is the appropriate usage:
```
var strongReferences: [Any]
func addActionToButton(button: UIButton) {
let token = button.addAction(for: .touchUpInside) {
print("Button Pressed")
}
self.strongReferences.append(token)
}
```
*/
public func addAction(for controlEvents: UIControlEvents, action: @escaping () -> Void) -> Any {
let targetAction = TargetAction(action: action)
self.addTarget(targetAction, action: #selector(targetAction.executeAction), for: controlEvents)
return targetAction
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment