BeeFramework 系列二 UISignal篇上

BeeFramework中用的最多的就是UISignal了,这是一种通过Bee框架体系实现的可替代Delegate的信号传递方式。通过它可以简化使用Delegate时的各种烦索。
继续第一篇的例子,我们把ViewController继承自BeeUIBoard。
#import <UIKit/UIKit.h>
#import <BeeFramework/Bee.h>

@interface ViewController : BeeUIBoard

@end

重新运行看看是否UISignal能路由到ViewController上
[img]http://dl2.iteye.com/upload/attachment/0085/3536/bcbb4fff-e6a2-306d-9d74-ac751ac46978.jpg[/img]
未看到路由到ViewController上,实际上UISignla已经路过ViewController了。查看BeeUIButton文件,发现各种事件最后都是通过sendUISignla来转发。
- (void)didTouchUpInside
{
if ( NO == [self testEvent:UIControlEventTouchUpInside] )
{
[self sendUISignal:BeeUIButton.TOUCH_UP_INSIDE];
}
}

跟踪UIView+BeeUISignal,可以看出在sendUISignal时,新建了一个BeeUISignal,并把自身(UIView)设置为Signal的target。
- (BeeUISignal *)sendUISignal:(NSString *)name withObject:(NSObject *)object from:(id)source
{
BeeUISignal * signal = [[[BeeUISignal alloc] init] autorelease];
if ( signal )
{
NSString * selName = self.tagString.lowercaseString;
selName = [selName stringByReplacingOccurrencesOfString:@"-" withString:@"_"];
// selName = [selName stringByReplacingOccurrencesOfString:@":" withString:@"_"];

signal.preSelector = selName; // v0.3.0 new feature, signal binding
signal.source = source ? source : self;
signal.target = self;
signal.name = name;
signal.object = object;
[signal send];
}
return signal;
}

跟踪BeeUISignal,发现其路由的核心在routes方法上,通过判断target是否实现规则的方法名,来决定最终调用的目标的View或ViewController,以此例为例,方法名可为handleUISignal_BeeUIButton_TOUCH_UP_INSIDE:或handleUISignal_BeeUIButton,如未找到该方法,则为继续判断是否响应以BeeUIButton父类命名的规则方法handleUIButton:,如此循环直至顶层类NSObject的规则方法handleNSObject:,最后实在未找到,则调用BeeUIButton的handleUISignal:方法。该方法在UIView+BeeUISignal中的实现:
- (void)handleUISignal:(BeeUISignal *)signal
{
if ( self.superview )
{
[signal forward:self.superview];
}
else
{
signal.reach = YES;

#if defined(__BEE_DEVELOPMENT__) && __BEE_DEVELOPMENT__
CC( @"[%@] > %@", signal.name, signal.callPath );
#endif // #if defined(__BEE_DEVELOPMENT__) && __BEE_DEVELOPMENT__
}
}

即把当前View的上一层再进行signal路由。

这里会发现signal未传到上一层的View进行路由。这里需要加下补丁,参考[url]https://github.com/ilikeido/BeeFramework/commit/59dc2e4c29ea1a890dafe47bf526ecf57b402c95[/url]
为Bee_UIBoard添加代码
-(id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
if ( nil == __allBoards )
{
__allBoards = [[NSMutableArray nonRetainingArray] retain];
}

[__allBoards insertObject:self atIndex:0];

_lastSleep = [NSDate timeIntervalSinceReferenceDate];
_lastWeekup = [NSDate timeIntervalSinceReferenceDate];

_zoomed = NO;
_zoomRect = CGRectZero;

_firstEnter = YES;
_presenting = NO;
_viewBuilt = NO;
_dataLoaded = NO;
_state = BeeUIBoard.STATE_DEACTIVATED;

_createDate = [[NSDate date] retain];

_modalAnimationType = BeeUIBoard.ANIMATION_TYPE_ALPHA;

_allowedPortrait = YES;
_allowedLandscape = NO;

#if defined(__BEE_DEVELOPMENT__) && __BEE_DEVELOPMENT__
_createSeq = __createSeed++;
_signalSeq = 0;
_signals = [[NSMutableArray alloc] init];

_callstack = [[NSMutableArray alloc] init];
[_callstack addObjectsFromArray:[BeeRuntime callstack:16]];
#endif // #if defined(__BEE_DEVELOPMENT__) && __BEE_DEVELOPMENT__

[self load];
}
return self;
}


修改UIView+BeeExtension.m 的ViewController方法
- (UIViewController *)viewController
{
if ( nil == self.superview )
return nil;

id nextResponder = [self nextResponder];
if ( [nextResponder isKindOfClass:[UIViewController class]] )
{
return (UIViewController *)nextResponder;
}
else
{
return nil;
}
}


好了,了解了signal的路由原理,现在在ViewController中添加
-(void)handleUISignal_BeeUIButton:(BeeUISignal *)signal{
if ([signal is:BeeUIButton.TOUCH_UP_INSIDE]) {
CC(@"111");
}

}

OK,重新运行。
[img]http://dl2.iteye.com/upload/attachment/0085/3587/c71422f2-0ee0-3b8d-abfc-5c52b551d8d1.png[/img]
现在有响应了,:-)。为了测试下signal是否是自底向上传递的。再来做个例子,打开ViewController.h添加个MyView
//
// ViewController.h
// BeeFrameWorkTest
//
// Created by he songhang on 13-6-3.
// Copyright (c) 2013年 he songhang. All rights reserved.
//

#import <UIKit/UIKit.h>
#import <BeeFramework/Bee.h>

@interface MyView : UIView

@end

@interface ViewController : BeeUIBoard

@end

修改ViewController.m
//
// ViewController.m
// BeeFrameWorkTest
//
// Created by he songhang on 13-6-3.
// Copyright (c) 2013年 he songhang. All rights reserved.
//

#import "ViewController.h"

@implementation MyView

-(void)handleUISignal_BeeUIButton:(BeeUISignal *)signal{
if ([signal is:BeeUIButton.TOUCH_UP_INSIDE]) {
CC(@"MyView response");
}
}

@end

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}

- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}

-(void)handleUISignal_BeeUIButton:(BeeUISignal *)signal{
if ([signal is:BeeUIButton.TOUCH_UP_INSIDE]) {
CC(@"ViewController response");
}
}

@end

打开ViewController.xib,添加一个MyView,并把Button继承自BeeUIButton放到MyView里
[img]http://dl2.iteye.com/upload/attachment/0085/3594/f68c3a6f-b97f-3ac3-a862-f7e5886d7405.jpg[/img]
重新运行,
可以看到点击Button,handleUISignal_BeeUIButton响应的是MyView,因为路由的路径是BeeUIButton->MyView.如果想让信号继续传递呢?对了添加[super handleUISignal:signal];
@implementation MyView

-(void)handleUISignal_BeeUIButton:(BeeUISignal *)signal{
if ([signal is:BeeUIButton.TOUCH_UP_INSIDE]) {
CC(@"MyView response");
}
[super handleUISignal:signal];
}

@end

现在的信号路由路径为
BeeUIButton->MyView->UIViewController

本文代码下载:[url]https://github.com/ilikeido/BeeFrameworkTest/tree/master/lesson2[/url]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值