Skip to content

Instantly share code, notes, and snippets.

@matrinox
Last active January 1, 2016 17:09
Show Gist options
  • Save matrinox/8175383 to your computer and use it in GitHub Desktop.
Save matrinox/8175383 to your computer and use it in GitHub Desktop.
Blocks over delegates
//
// GABlockDelegate.h
// GAToolkit
//
// Created by Geoff on 12/29/2013.
// Copyright (c) 2013 Geoff. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface GABlockDelegate : NSObject <UIAlertViewDelegate, UIActionSheetDelegate>
// UIControl
+ (void)addBlock:(void (^)(id object))block toUIControl:(UIControl *)control;
+ (void)addBlock:(void (^)(id object))block toUIControl:(UIControl *)control forControlEvents:(UIControlEvents)controlEvent;
+ (void)removeBlockFromUIControl:(UIControl *)control;
// UIAlertView
+ (void)showAlertViewWithTitle:(NSString *)title message:(NSString *)message cancelTitle:(NSString *)cancelTitle otherTitles:(NSArray *)otherTitles responseHandler:(void (^)(UIAlertView *alertView, NSString *string))block;
+ (void)showAlertView:(UIAlertView *)alertView withResponseHandler:(void (^)(UIAlertView *alertView, NSString *buttonTitle))block;
+ (void)setAlertView:(UIAlertView *)alertView withResponseHandler:(void (^)(UIAlertView *alertView, NSString *buttonTitle))block;
// UIActionSheet
+ (UIActionSheet *)createActionSheetWithTitle:(NSString *)title cancelTitle:(NSString *)cancelTitle destructiveTitle:(NSString *)destructiveTitle otherTitles:(NSArray *)otherTitles withResponseHandler:(void (^)(UIActionSheet *actionSheet, NSString *buttonTitle))block;
+ (void)setActionSheet:(UIActionSheet *)actionSheet withResponseHandler:(void (^)(UIActionSheet *actionSheet, NSString *buttonTitle))block;
// Gesture
+ (void)setGestureRecognizer:(UIGestureRecognizer *)gesture withResponseHandler:(void (^)(UIGestureRecognizer *gestureRecognizer, UIGestureRecognizerState state))block;
+ (void)removeGestureRecognizer:(UIGestureRecognizer *)gesture;
@end
//
// GABlockDelegate.m
// GAToolkit
//
// Created by Geoff on 12/29/2013.
// Copyright (c) 2013 Geoff. All rights reserved.
//
#import "GABlockDelegate.h"
#import <objc/runtime.h>
static char controlEventsKey;
static char alertViewKey;
static char actionSheetKey;
static char gestureKey;
@implementation GABlockDelegate
#pragma mark -
#pragma mark UIControl
+ (void)addBlock:(void (^)(id))block toUIControl:(UIControl *)control {
UIControlEvents controlEvent = UIControlEventTouchUpInside;
if ( [control conformsToProtocol:@protocol(UITextInput)] ) {
controlEvent = UIControlEventValueChanged;
}
else if ( [control isKindOfClass:[UISlider class]] ) {
controlEvent = UIControlEventValueChanged;
}
else if ( [control isKindOfClass:[UIStepper class]] ) {
controlEvent = UIControlEventValueChanged;
}
else if ( [control isKindOfClass:[UIDatePicker class]] ) {
controlEvent = UIControlEventValueChanged;
}
else if ( [control isKindOfClass:[UIPickerView class]] ) {
controlEvent = UIControlEventValueChanged;
}
[self addBlock:block toUIControl:control forControlEvents:controlEvent];
}
+ (void)addBlock:(void (^)(id))block toUIControl:(UIControl *)control forControlEvents:(UIControlEvents)controlEvent {
objc_setAssociatedObject(control, &controlEventsKey, block, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
[control addTarget:self action:@selector(respondToUIControl:) forControlEvents:controlEvent];
}
+ (void)removeBlockFromUIControl:(UIControl *)control {
objc_removeAssociatedObjects(control);
}
+ (void)respondToUIControl:(UIControl *)control {
void (^block)(id) = objc_getAssociatedObject(control, &controlEventsKey);
block(control);
}
#pragma mark -
#pragma mark UIAlertView
+ (void)showAlertViewWithTitle:(NSString *)title message:(NSString *)message cancelTitle:(NSString *)cancelTitle otherTitles:(NSArray *)otherTitles responseHandler:(void (^)(UIAlertView *, NSString *))block {
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:title message:message delegate:self cancelButtonTitle:nil otherButtonTitles:Nil];
for ( NSString *title in otherTitles ) {
[alertView addButtonWithTitle:title];
}
if ( cancelTitle ) {
alertView.cancelButtonIndex = [alertView addButtonWithTitle:cancelTitle];
}
[self showAlertView:alertView withResponseHandler:block];
}
+ (void)showAlertView:(UIAlertView *)alertView withResponseHandler:(void (^)(UIAlertView *, NSString *))block {
[self setAlertView:alertView withResponseHandler:block];
[alertView show];
}
+ (void)setAlertView:(UIAlertView *)alertView withResponseHandler:(void (^)(UIAlertView *, NSString *))block {
alertView.delegate = self;
objc_setAssociatedObject(alertView, &alertViewKey, block, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
+ (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
void (^block)(UIAlertView *, NSString *) = objc_getAssociatedObject(alertView, &alertViewKey);
block(alertView,[alertView buttonTitleAtIndex:buttonIndex]);
}
+ (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex {
objc_removeAssociatedObjects(alertView);
}
#pragma mark -
#pragma mark UIActionSheet
+ (UIActionSheet *)createActionSheetWithTitle:(NSString *)title cancelTitle:(NSString *)cancelTitle destructiveTitle:(NSString *)destructiveTitle otherTitles:(NSArray *)otherTitles withResponseHandler:(void (^)(UIActionSheet *, NSString *))block {
UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:title delegate:(id <UIActionSheetDelegate>)self cancelButtonTitle:nil destructiveButtonTitle:nil otherButtonTitles:nil];
for ( NSString *title in otherTitles ) {
[actionSheet addButtonWithTitle:title];
}
if ( cancelTitle ) {
actionSheet.cancelButtonIndex = [actionSheet addButtonWithTitle:cancelTitle];
}
if ( destructiveTitle ) {
actionSheet.destructiveButtonIndex = [actionSheet addButtonWithTitle:destructiveTitle];
}
[self setActionSheet:actionSheet withResponseHandler:block];
return actionSheet;
}
+ (void)setActionSheet:(UIActionSheet *)actionSheet withResponseHandler:(void (^)(UIActionSheet *, NSString *))block {
actionSheet.delegate = (id <UIActionSheetDelegate>)self;
objc_setAssociatedObject(actionSheet, &actionSheetKey, block, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
+ (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
void (^block)(UIActionSheet *, NSString *) = objc_getAssociatedObject(actionSheet, &actionSheetKey);
block(actionSheet,[actionSheet buttonTitleAtIndex:buttonIndex]);
}
+ (void)actionSheet:(UIActionSheet *)actionSheet didDismissWithButtonIndex:(NSInteger)buttonIndex {
objc_removeAssociatedObjects(actionSheet);
}
#pragma mark -
#pragma mark Gestures
+ (void)setGestureRecognizer:(UIGestureRecognizer *)gesture withResponseHandler:(void (^)(UIGestureRecognizer *, UIGestureRecognizerState))block {
objc_setAssociatedObject(gesture, &gestureKey, block, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
[gesture addTarget:self action:@selector(handleGesture:)];
}
+ (void)handleGesture:(UIGestureRecognizer *)gesture {
void (^block)(UIGestureRecognizer *, UIGestureRecognizerState) = objc_getAssociatedObject(gesture, &gestureKey);
block(gesture, gesture.state);
}
+ (void)removeGestureRecognizer:(UIGestureRecognizer *)gesture {
objc_removeAssociatedObjects(gesture);
}
@end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment