代码之家  ›  专栏  ›  技术社区  ›  Ben Scheirman

uibutton块等效于addTarget:action:forControlEvents:method?

  •  60
  • Ben Scheirman  · 技术社区  · 14 年前

    我环顾四周,但在互联网上或苹果文档中的任何地方都找不到这个,所以我猜想它不存在。

    但是,是否有一个IOS4块相当于以下API:

    [button addTarget:self action:@selector(tappy:) forControlEvents:UIControlEventTouchUpInside];
    

    我想这可以用一个类别来实现,但是我不想自己写,因为 极端 懒惰:

    像这样的事情会很棒:

    [button handleControlEvent:UIControlEventTouchUpInside withBlock:^ { NSLog(@"I was tapped!"); }];
    
    9 回复  |  直到 14 年前
        1
  •  51
  •   mylogon    8 年前

    typedef void (^ActionBlock)();
    
    @interface UIBlockButton : UIButton {
        ActionBlock _actionBlock;
    }
    
    -(void) handleControlEvent:(UIControlEvents)event
                     withBlock:(ActionBlock) action;
    @end
    
    @implementation UIBlockButton
    
    -(void) handleControlEvent:(UIControlEvents)event
                     withBlock:(ActionBlock) action
    {
        _actionBlock = action;
        [self addTarget:self action:@selector(callActionBlock:) forControlEvents:event];
    }
    
    -(void) callActionBlock:(id)sender{
        _actionBlock();
    }
    @end
    
        2
  •  23
  •   Cfr    10 年前

    BlocksKit documentation

    UIControl category

    [button addEventHandler:^(id sender) {
        //do something
    } forControlEvents:UIControlEventTouchUpInside];
    

        3
  •  22
  •   Shayne Sweeney    14 年前

    DEBUG #ifdef DEBUG

    #ifdef DEBUG
    
    #import <objc/runtime.h>
    
    static char UIButtonBlockKey;
    
    @interface UIButton (UIBlockButton)
    
    - (void)handleControlEvent:(UIControlEvents)event withBlock:(ActionBlock)block;
    - (void)callActionBlock:(id)sender;
    
    @end
    
    
    @implementation UIButton (UIBlockButton)
    
    - (void)handleControlEvent:(UIControlEvents)event withBlock:(ActionBlock)block {
        objc_setAssociatedObject(self, &UIButtonBlockKey, block, OBJC_ASSOCIATION_COPY_NONATOMIC);
        [self addTarget:self action:@selector(callActionBlock:) forControlEvents:event];
    }
    
    
    - (void)callActionBlock:(id)sender {
        ActionBlock block = (ActionBlock)objc_getAssociatedObject(self, &UIButtonBlockKey);
        if (block) {
            block();
        }
    }
    
    @end
    
    
    void DSAddGlobalButton(NSString *title, ActionBlock block) {
        UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
        [button setTitle:title forState:UIControlStateNormal];
        [button handleControlEvent:UIControlEventTouchUpInside withBlock:block];
        [button sizeToFit];
        [button setFrame:(CGRect){{100.0f, 100.0f}, [button frame].size}];
    
        UIView *firstView = [[[[UIApplication sharedApplication] keyWindow] subviews] objectAtIndex:0];
        [firstView addSubview:button];
    }
    
    
    #endif
    
        4
  •  7
  •   dimohamdy    8 年前

    UIControl UIButton UIBarButtonItem UIGestureRecognizer

    https://github.com/lavoy/ALActionBlocks

    // Assuming you have a UIButton named 'button'
    [button handleControlEvents:UIControlEventTouchUpInside withBlock:^(id weakControl) {
        NSLog(@"button pressed");
    }];
    

    pod 'ALActionBlocks'
    
        5
  •  7
  •   levin varghese    6 年前

    class ClosureSleeve {
    let closure: () -> ()
    
    init(attachTo: AnyObject, closure: @escaping () -> ()) {
        self.closure = closure
        objc_setAssociatedObject(attachTo, "[\(arc4random())]", self, .OBJC_ASSOCIATION_RETAIN)
    }
    
    @objc func invoke() {
        closure()
      }
    }
    
    extension UIControl {
    func addAction(for controlEvents: UIControlEvents = .primaryActionTriggered, action: @escaping () -> ()) {
        let sleeve = ClosureSleeve(attachTo: self, closure: action)
        addTarget(sleeve, action: #selector(ClosureSleeve.invoke), for: controlEvents)
     }
    }
    

    button.addAction {
    print("button pressed")
    }
    
        6
  •  5
  •   Gabe    12 年前

    #import <UIKit/UIKit.h>
    
    @interface ButtWithBlockActions : UIButton {
      void (^downBlock_)(void);
      void (^upBlock_)(void);
      void (^clickedBlock_)(void);
    }
    
    @property(nonatomic,retain) void (^downBlock)(void);
    @property(nonatomic,retain) void (^upBlock)(void);
    @property(nonatomic,retain) void (^clickedBlock)(void);
    
    @end
    
    
    
    #import "ButtWithBlockActions.h"
    
    @implementation ButtWithBlockActions
    
    - (void)dealloc {
      [downBlock_ release];
      [upBlock_ release];
      [clickedBlock_ release];
      [super dealloc];
    }
    
    
    - (void (^)(void))downBlock { return downBlock_; }
    - (void) fireDownBlock { downBlock_(); }
    - (void) setDownBlock:(void (^)(void))block {
      if(downBlock_) {
        [self removeTarget:self action:@selector(fireDownBlock) forControlEvents:UIControlEventTouchDown];
        [self removeTarget:self action:@selector(fireDownBlock) forControlEvents:UIControlEventTouchDragEnter];
        [downBlock_ release];
      }
      downBlock_ = [block copy];
      if(downBlock_) {
        [self addTarget:self action:@selector(fireDownBlock) forControlEvents:UIControlEventTouchDown];
        [self addTarget:self action:@selector(fireDownBlock) forControlEvents:UIControlEventTouchDragEnter];
      }
    }
    
    
    - (void (^)(void))upBlock { return upBlock_; }
    - (void) fireUpBlock { upBlock_(); }
    - (void) setUpBlock:(void (^)(void))block {
      if(upBlock_) {
        [self removeTarget:self action:@selector(fireUpBlock) forControlEvents:UIControlEventTouchUpInside];
        [self removeTarget:self action:@selector(fireUpBlock) forControlEvents:UIControlEventTouchUpOutside];
        [self removeTarget:self action:@selector(fireUpBlock) forControlEvents:UIControlEventTouchDragOutside];
        [self removeTarget:self action:@selector(fireUpBlock) forControlEvents:UIControlEventTouchCancel];
        [upBlock_ release];
      }
      upBlock_ = [block copy];
      if(upBlock_) {
        [self addTarget:self action:@selector(fireUpBlock) forControlEvents:UIControlEventTouchUpInside];
        [self addTarget:self action:@selector(fireUpBlock) forControlEvents:UIControlEventTouchUpOutside];
        [self addTarget:self action:@selector(fireUpBlock) forControlEvents:UIControlEventTouchDragOutside];
        [self addTarget:self action:@selector(fireUpBlock) forControlEvents:UIControlEventTouchCancel];
      }
    }
    
    
    - (void (^)(void))clickedBlock { return clickedBlock_; }
    - (void) fireClickedBlock { clickedBlock_(); }
    - (void) setClickedBlock:(void (^)(void))block {
      if(clickedBlock_) {
        [self removeTarget:self action:@selector(fireClickedBlock) forControlEvents:UIControlEventTouchUpInside];
        [clickedBlock_ release];
      }
      clickedBlock_ = [block copy];
      if(clickedBlock_) {
        [self addTarget:self action:@selector(fireClickedBlock) forControlEvents:UIControlEventTouchUpInside];
      }
    }
    
    @end
    
        7
  •  1
  •   Kazki    12 年前

    REKit

    id target;
    target = [[NSObject alloc] init];
    [target respondsToSelector:@selector(buttonAction) withKey:nil usingBlock:^(id receiver) {
        // Do something…
    }];
    [button addTarget:target action:@selector(buttonAction) forControlEvents:UIControlEventTouchUpInside];
    

        8
  •  1
  •   yeoman    8 年前

    @interface Handler : NSObject
    
    @end
    
    @implementation Handler {
        void (^block)(id);
    }
    
    + (Handler *)create:(void (^)(id))block {
        Handler *result = [[Handler alloc] init];
    
        result->block = block;
    
        return result;
    }
    
    - (void)call:(id)sender {
        block(sender);
    }
    
    @end
    

    Handler *handler = [Handler create:^(id sender) {
        // ... handle the event, using local state captured by the block ...
    }];
    
    // store the handler because the target is not retained in addTarget
    [handlers addObject:handler];
    
    [button addTarget:handler action:@selector(call:) forControlEvents:UIControlEventTouchUpInside];
    
        9
  •  0
  •   BadPirate    8 年前

    import UIKit
    
    // MARK: UIControl Block based actions
    typealias ActionBlock = (UIControl) -> ()
    
    class UIButtonActionDelegate : NSObject {
        let actionBlock : ActionBlock
        init(actionBlock: ActionBlock) {
            self.actionBlock = actionBlock
        }
        func triggerBlock(control : UIControl) {
            actionBlock(control)
        }
    }
    
    private var actionHandlersKey: UInt8 = 0
    extension UIControl {
        var actionHandlers: NSMutableArray { // cat is *effectively* a stored property
            get {
                return associatedObject(self, key: &actionHandlersKey, initialiser: { () -> NSMutableArray in
                    return NSMutableArray()
                })
            }
            set { associateObject(self, key: &actionHandlersKey, value: newValue) }
        }
    
        func addBlockForEvents(events: UIControlEvents, block: ActionBlock) {
            let actionDelegate = UIButtonActionDelegate(actionBlock: block)
            actionHandlers.addObject(actionDelegate) // So it gets retained
            addTarget(actionDelegate, action: #selector(UIButtonActionDelegate.triggerBlock(_:)), forControlEvents: events)
        }
    }
    
    // MARK: Associated Object wrapper
    
    func associatedObject<ValueType: AnyObject>(
        base: AnyObject,
        key: UnsafePointer<UInt8>,
        initialiser: () -> ValueType)
        -> ValueType {
            if let associated = objc_getAssociatedObject(base, key)
                as? ValueType { return associated }
            let associated = initialiser()
            objc_setAssociatedObject(base, key, associated,
                                     .OBJC_ASSOCIATION_RETAIN)
            return associated
    }
    
    func associateObject<ValueType: AnyObject>(
        base: AnyObject,
        key: UnsafePointer<UInt8>,
        value: ValueType) {
        objc_setAssociatedObject(base, key, value,
                                 .OBJC_ASSOCIATION_RETAIN)
    }