UIButton block equivalent to addTarget:action:forControlEvents: method?

后端 未结 9 1216
旧巷少年郎
旧巷少年郎 2020-11-29 20:58

I looked around, but couldn\'t find this on the internet, nor anywhere in the Apple docs, so I\'m guessing it doesn\'t exist.

But is there a iOS4 blocks equivalent A

9条回答
  •  日久生厌
    2020-11-29 21:22

    I WROTE THIS LONG AGO AND IT'S NOT THE WAY TO SOLVE THIS PROBLEM!!! Subclassing UIButton creates a minefield that just isn't worth it. Use Shayne Sweeney's Category(I just updated his answer with a bunch of tweaks to make his example production ready... hopefully they get approved quickly).

    -----ORIG POST-----

    The code posted by Martin should work if you are only assigning the UIControlEventTouchUpInside... but there are a couple problems:

    • You will leak blocks with the code posted if you call handleControlEvent: more than once.
    • If you assign more than one type of event, it will fire the last block for all events

    In my code I'm relying on Blocks being treated as object-c objects, which only works on iOS4+(not 3.2). It works well for me when I want to do something special for button states(i.e. animations). You can just use the clickedButton block for handling normal clicks.

    #import 
    
    @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
    

提交回复
热议问题