Ben*_*man 62 iphone uibutton objective-c-blocks
我环顾四周,但在互联网上找不到这个,也没有找到Apple文档中的任何地方,所以我猜它不存在.
但是有一个iOS4块等效API来:
[button addTarget:self action:@selector(tappy:) forControlEvents:UIControlEventTouchUpInside];
Run Code Online (Sandbox Code Playgroud)
我想这可以使用一个类别来实现,但是由于极端的懒惰而宁愿不写这个:)
像这样的东西会很棒:
[button handleControlEvent:UIControlEventTouchUpInside withBlock:^ { NSLog(@"I was tapped!"); }];
Run Code Online (Sandbox Code Playgroud)
Mar*_*chl 55
我刚刚实现了这个.它的工作就像一个魅力!
它甚至都不难.
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
Run Code Online (Sandbox Code Playgroud)
Cfr*_*Cfr 23
常见的Foundation/UI类增加了一个块库:BlocksKit.这是文档.
它不是UIButton的子类,但添加了UIControl类别:
[button addEventHandler:^(id sender) {
//do something
} forControlEvents:UIControlEventTouchUpInside];
Run Code Online (Sandbox Code Playgroud)
集合(地图,过滤器等),视图相关的东西等也有块/功能添加.
注意:它与Swift不兼容.
Sha*_*ney 22
这是一个工作类别实现.在它的当前形式中,这应该仅用于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
Run Code Online (Sandbox Code Playgroud)
斯威夫特4
这是快速的解决方案
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)
}
}
Run Code Online (Sandbox Code Playgroud)
用法示例:
button.addAction {
print("button pressed")
}
Run Code Online (Sandbox Code Playgroud)
我创建了一个库来做这个!
它支持UIControl(UIButton)UIBarButtonItem,和UIGestureRecognizer.它也支持使用CocoaPods.
https://github.com/lavoy/ALActionBlocks
// Assuming you have a UIButton named 'button'
[button handleControlEvents:UIControlEventTouchUpInside withBlock:^(id weakControl) {
NSLog(@"button pressed");
}];
Run Code Online (Sandbox Code Playgroud)
安装
pod 'ALActionBlocks'
Run Code Online (Sandbox Code Playgroud)
我把这个问题彻底解决了,而不是解决这个问题的方法!对UIButton进行子类化创建了一个不值得的雷区.使用Shayne Sweeney的分类(我刚刚通过一系列调整更新了他的答案,以使他的示例生产准备就绪......希望他们能够快速获得批准).
----- ORIG POST -----
如果您只分配UIControlEventTouchUpInside,那么Martin发布的代码应该可以工作......但是有一些问题:
在我的代码中,我依赖于块被视为object-c对象,它只适用于iOS4 +(而不是3.2).当我想为按钮状态(即动画)做一些特别的事情时,它对我很有用.您可以使用clickedButton块来处理正常点击.
#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
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
33671 次 |
| 最近记录: |