From 00a2d672bf609a3cb396a4303868804e8d376fa8 Mon Sep 17 00:00:00 2001 From: Ivan Misuno Date: Fri, 1 Jan 2016 16:49:04 +0100 Subject: [PATCH] Add Reactive bindings for UIBarButtonItem --- ReactiveUIKit.xcodeproj/project.pbxproj | 4 ++ ReactiveUIKit/UIBarButtonItem.swift | 63 +++++++++++++++++++++++++ 2 files changed, 67 insertions(+) create mode 100644 ReactiveUIKit/UIBarButtonItem.swift diff --git a/ReactiveUIKit.xcodeproj/project.pbxproj b/ReactiveUIKit.xcodeproj/project.pbxproj index 1366de0..1553d01 100644 --- a/ReactiveUIKit.xcodeproj/project.pbxproj +++ b/ReactiveUIKit.xcodeproj/project.pbxproj @@ -7,6 +7,7 @@ objects = { /* Begin PBXBuildFile section */ + 782B49D81C36D52100E5979D /* UIBarButtonItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 782B49D71C36D52100E5979D /* UIBarButtonItem.swift */; }; EC9549321BF1D8A7000FC2BF /* UICollectionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC9549311BF1D8A7000FC2BF /* UICollectionView.swift */; }; EC9549341BF1DC52000FC2BF /* UIControl.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC9549331BF1DC52000FC2BF /* UIControl.swift */; }; EC9549361BF1DE78000FC2BF /* UIButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC9549351BF1DE78000FC2BF /* UIButton.swift */; }; @@ -66,6 +67,7 @@ /* Begin PBXFileReference section */ 16E125A11BF5056C00543EFB /* ReactiveUIKit.podspec */ = {isa = PBXFileReference; lastKnownFileType = text; path = ReactiveUIKit.podspec; sourceTree = ""; }; 16E125A21BF5056C00543EFB /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; + 782B49D71C36D52100E5979D /* UIBarButtonItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIBarButtonItem.swift; sourceTree = ""; }; EC9549311BF1D8A7000FC2BF /* UICollectionView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UICollectionView.swift; sourceTree = ""; }; EC9549331BF1DC52000FC2BF /* UIControl.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIControl.swift; sourceTree = ""; }; EC9549351BF1DE78000FC2BF /* UIButton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIButton.swift; sourceTree = ""; }; @@ -165,6 +167,7 @@ children = ( ECB7A5441BEB71E10034053A /* ReactiveUIKit.h */, ECB7A5631BEB72380034053A /* UIView.swift */, + 782B49D71C36D52100E5979D /* UIBarButtonItem.swift */, ECB7A55C1BEB72380034053A /* UIBarItem.swift */, ECB7A55D1BEB72380034053A /* UIImageView.swift */, ECB7A55E1BEB72380034053A /* UILabel.swift */, @@ -377,6 +380,7 @@ EC95493A1BF1E12E000FC2BF /* UISegmentedControl.swift in Sources */, EC9549341BF1DC52000FC2BF /* UIControl.swift in Sources */, EC95493E1BF1E286000FC2BF /* UISwitch.swift in Sources */, + 782B49D81C36D52100E5979D /* UIBarButtonItem.swift in Sources */, ECB7A56C1BEB72380034053A /* UIView.swift in Sources */, ECB7A5651BEB72380034053A /* UIBarItem.swift in Sources */, ECB7A5691BEB72380034053A /* UIProgressView.swift in Sources */, diff --git a/ReactiveUIKit/UIBarButtonItem.swift b/ReactiveUIKit/UIBarButtonItem.swift new file mode 100644 index 0000000..f55c56e --- /dev/null +++ b/ReactiveUIKit/UIBarButtonItem.swift @@ -0,0 +1,63 @@ +// +// UIBarButtonItem.swift +// ReactiveUIKit +// +// Created by Ivan Misuno on 01/01/16. +// Copyright © 2016 Srdan Rasic. All rights reserved. +// + +import UIKit +import ReactiveKit +import ReactiveFoundation + +@objc class RKUIBarButtonItemHelper: NSObject +{ + weak var barButtonItem: UIBarButtonItem? + let observer: Void -> Void + + init(barButtonItem: UIBarButtonItem, observer: Void -> Void) { + self.barButtonItem = barButtonItem + self.observer = observer + super.init() + if barButtonItem.target != nil { + NSLog("Hijacking existing UIBarButtonItem's target and action: \(barButtonItem)") + } + barButtonItem.target = self + barButtonItem.action = Selector("eventHandler:") + } + + func eventHandler(sender: AnyObject) { + observer() + } + + deinit { + barButtonItem?.target = nil + } +} + +extension UIBarButtonItem { + + private struct AssociatedKeys { + static var BarButtonItemActionKey = "r_BarButtonItemActionKey" + static var BarButtonItemBondHelperKey = "r_BarButtonItemBondHelperKey" + } + + public var rAction: ActiveStream { + if let rAction: AnyObject = objc_getAssociatedObject(self, &AssociatedKeys.BarButtonItemActionKey) { + return rAction as! ActiveStream + } else { + var capturedObserver: (Void -> Void)! = nil + + let rAction = ActiveStream { observer in + capturedObserver = observer + return nil + } + + let barButtonItemHelper = RKUIBarButtonItemHelper(barButtonItem: self, observer: capturedObserver) + + objc_setAssociatedObject(self, &AssociatedKeys.BarButtonItemBondHelperKey, barButtonItemHelper, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC) + objc_setAssociatedObject(self, &AssociatedKeys.BarButtonItemActionKey, rAction, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC) + return rAction + } + } +}