以上2种需求,我想大多数开发者都遇到过,并且可以实现这种功能。毕竟,这是比较基础的功能。但是代码未必那么优雅。
针对 1.
,一般初学者会用target或者block等方法在tableView的代理方法拿到事件,并把要执行的跳转写到controller里。功能是可以实现的,但问题是这种cell及相似的cell(布局有些变化,或者多几个少几个控件)一般出现在多个页面。这样的话相同的代码就会出现在多个地方。就算把跳转方法抽取出来写成category,但是target或者block总是每个地方都要写的。
针对 2.
,初级的方法是每个地方写一坨判断及跳转,高级一些是抽取出来写在基类或者category。
纵观上面各种情况,总结起来就是一句话, 在任意的地方触发事件(可以是推送,拦截的js跳转,各种控件的点击事件)可以跳转到任意界面。
所以我们可以统一用一个控制跳转的manager来完成跳转。
与后端约定好数据结构,例如:
NSDictionary *target = @{@"action" : @"user",
@"data" : @{@"user_id" : @(123456)}};
就是跳转到id为123456的用户页面,如果跳转需要更多的数据,可以在data的value里面继续添加。
创建一个用来跳转的类,可以起的牛x的名字,XXCoreActionManager。创建一个类方法:
+ (BOOL)doActionForTarget:(NSDictionary *)target{
//根据你的app结构,来取得你当前的controller,由它来进行跳转
UIApplication *application = [UIApplication sharedApplication];
AppDelegate *myAppDelegate = (AppDelegate *)[application delegate];
UIViewController *viewController;
if ([myAppDelegate getTabbarSelectedView]) {
viewController = [myAppDelegate getTabbarSelectedView].visibleViewController;
}else {
return NO;
}
if([json[@"action"] isEqualToString:@"film_view"]){
MFMaterialListViewController *materialListVC = [[MFMaterialListViewController alloc] initWithNibName:@"MFMaterialListViewController" bundle:nil];
materialListVC.hidesBottomBarWhenPushed = YES;
materialListVC.filmId = json[@"data"][@"film_id"];
[viewController.navigationController pushViewController:materialListVC animated:YES];
return YES;
}else if([json[@"action"] isEqualToString:@"home"]){
[myAppDelegate getTabbar].selectedIndex = 0;
[viewController.navigationController popToRootViewControllerAnimated:YES];
return YES;
}
return NO;
}
在刚才定义的数据结构中, action
的值为需要跳转的页面, data
的值跳转所需要要的参数,比如 id
、 type
等。服务器只需要传入相应的数据就可以用
[XXCoreActionManager doActionForTarget:target];
来进行跳转。真正的 write once,use anywhere
针对头像、评论、转发等多处使用的子控件,可以把事件由自己接收,通过XXCoreActionManager来进行跳转。即做到了代码分离,使之成为真正独立的控件,便于复用。
下面是一个简单例子:
@implementation MFUserHeadButton
-(void)awakeFromNib{
[self addTarget:self action:@selector(toUserDetail) forControlEvents:UIControlEventTouchUpInside];
}
- (void)toUserDetail{
NSDictionary *target = @{@"action":@"user",
@"data":@{@"user_id":@(self.tag)}};
[XXCoreActionManager doActionForTarget:target];
}
这就是一个简单的实现跳转到个人页功能的头像控件实现。
如果你问 user_id
的值怎么来的?
当然是configCell的时候传给view的 tag
的。
你可能会说,我的跳转需要多个参数啊,你一个tag不够用啊亲。
可以定义一个NSDictionary属性接收啊。
如果你用原生的UI控件,那让强大的runtime给你加喽
- (void)setDict:(NSDictionary *)dict {
objc_setAssociatedObject(self, dictKey, dict, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (NSDictionary *)dict {
return objc_getAssociatedObject(self, dictKey);
}
write once,use anywhere
。 从读大学接触到计算机技术这一领域,我就被这个圈子的氛围深深的触动了,这是一个如此自由、分享、开放的圈子。我从无数人的的分享中汲取着知识(开源的代码,分享的博客),我受益于这种环境,我就想对它做出回馈,写出这篇文章,即希望能帮助一些人,也希望能与大家有更多的交流。最后,谢谢那些无私的做出各种奉献的人。