Skip to content

Instantly share code, notes, and snippets.

@rhysforyou
Created October 12, 2015 23:25
Show Gist options
  • Save rhysforyou/2fb029ee5f0a9c1e0858 to your computer and use it in GitHub Desktop.
Save rhysforyou/2fb029ee5f0a9c1e0858 to your computer and use it in GitHub Desktop.
ReactiveCocoa 4 UIKit Extensions
//
// UIKitExtensions.swift
// ReactiveForms
//
// Created by Rhys Powell on 12/10/2015.
// Copyright © 2015 Rhys Powell. All rights reserved.
//
import Foundation
import ReactiveCocoa
func lazyAssociatedProperty<T: AnyObject>(host: AnyObject,
key: UnsafePointer<Void>, factory: ()->T) -> T {
var associatedProperty = objc_getAssociatedObject(host, key) as? T
if associatedProperty == nil {
associatedProperty = factory()
objc_setAssociatedObject(host, key, associatedProperty,
.OBJC_ASSOCIATION_RETAIN)
}
return associatedProperty!
}
func lazyMutableProperty<T>(host: AnyObject, key: UnsafePointer<Void>,
setter: T -> (), getter: () -> T) -> MutableProperty<T> {
return lazyAssociatedProperty(host, key: key) {
let property = MutableProperty<T>(getter())
property.producer
.startWithNext { setter($0) }
return property
}
}
struct AssociationKey {
static var hidden: UInt8 = 1
static var alpha: UInt8 = 2
static var text: UInt8 = 3
static var enabled: UInt8 = 4
static var action: UInt8 = 5
}
extension UIView {
public var rac_hidden: MutableProperty<Bool> {
return lazyMutableProperty(self, key: &AssociationKey.hidden, setter: { self.hidden = $0 }, getter: { return self.hidden })
}
public var rac_alpha: MutableProperty<CGFloat> {
return lazyMutableProperty(self, key: &AssociationKey.alpha, setter: { self.alpha = $0 }, getter: { return self.alpha })
}
}
extension UITextField {
public var rac_text: MutableProperty<String> {
return lazyAssociatedProperty(self, key: &AssociationKey.text) {
self.addTarget(self, action: "rac_textChanged", forControlEvents: UIControlEvents.EditingChanged)
let property = MutableProperty<String>(self.text ?? "")
property.producer.startWithNext { self.text = $0 }
return property
}
}
func rac_textChanged() {
rac_text.value = self.text ?? ""
}
}
extension UIControl {
var rac_enabled: MutableProperty<Bool> {
return lazyMutableProperty(self, key: &AssociationKey.enabled, setter: { self.enabled = $0 }, getter: { return self.enabled })
}
}
extension UIButton {
var rac_action: Action<AnyObject?, Void, NoError>? {
get {
return objc_getAssociatedObject(self, &AssociationKey.action) as? Action<AnyObject?, Void, NoError>
}
set(action) {
// Unbind old action
if let oldAction = self.rac_action {
self.removeTarget(oldAction.unsafeCocoaAction, action: CocoaAction.selector, forControlEvents: .TouchUpInside)
}
// Store and bind new action
objc_setAssociatedObject(self, &AssociationKey.action, action, .OBJC_ASSOCIATION_RETAIN)
if let action = action {
self.rac_enabled <~ action.enabled
self.addTarget(action.unsafeCocoaAction, action: CocoaAction.selector, forControlEvents: .TouchUpInside)
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment