Iphone 通过多层次结构传递委托
我编写了一个自定义类TagsScrollView,它在滚动视图中显示标记 当按下标记时,TagsScrollView依赖其委托来执行操作。几乎所有时候,这都涉及:Iphone 通过多层次结构传递委托,iphone,objective-c,Iphone,Objective C,我编写了一个自定义类TagsScrollView,它在滚动视图中显示标记 当按下标记时,TagsScrollView依赖其委托来执行操作。几乎所有时候,这都涉及: 将选项卡索引更改为其他索引 将TagsDetailVC按到当前导航控制器 现在,这就是我的应用程序的结构: 虚线表示“有”关系。MainVC有一个FeedView,它有几个FeedCellView,每个FeedCellView又有一个TagsScrollView 实线表示“推送”关系。ImageDetailVc被推送到MainVC的
@protocol TagPressedDelegate<NSObject>
@required
- (void)tagPressed:(id)sender forQuery:(NSString *)query;
@end
如何避免这种模式?我能做得更好吗?我应该改为使用标记ScrollViewDelegate扩展ScrollViewDelegate吗 您肯定可以做得更好,删除委派模式,使用块 将基于块的属性添加到TagsScrollView.h文件中
@property(复制,非原子)void(^tagPressedBlock)(id发送者,NSString*查询)代码>
在.m文件中添加相关回调
- (void)tagPressed:(id)sender {
if (_tagPressedBlock) {
_tagPressedBlock(sender, self.query); // I'm assuming that the query is your iVar
}
}
像这样分配属性
tagsScrollView.tagPressedBlock = ^(id sender, NSString *query) {
// do stuff with those parameters
}
那是为了“做得更好”
至于如何将标记按下事件传递给MainVC
类,您应该使用NSNotificationCenter
在全局可见的位置定义通知名称,例如,我建议创建一个Defines.h文件,并将其包含在Prefix.pch文件中
无论如何,请定义通知名称:
静态NSString*const TagPressedNotification=@“TagPressedNotification”代码>
下一步在执行-tagPressed:
时发布该通知,并将有价值的信息封装到userInfo字典中:
- (void)tagPressed:(id)sender {
[[NSNotificationCenter defaultCenter] postNotificationName:TagPressedNotification object:nil userInfo:@{@"sender" : sender, @"query" : self.query, @"scrollView" : self.tagScrollView}];
//.. code
}
接下来,将您的MainVC
作为观察员添加到该通知中:
MainVC.m
- (void)viewDidLoad {
[super viewDidLoad];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(tagPressed:)
name:TagPressedNotification
object:nil];
}
并在MainVC中实现-tagPressed:
方法
- (void)tagPressed:(NSNotification *)notification {
id sender = notification.userInfo[@"sender"];
NSString *query = notification.userInfo[@"query"];
TagScrollView *scrollView = notification.userInfo[@"scrollView"];
if (scrollView == myScrollView) { // the one on your mainVC
// do stuff
}
}
添加不要忘记将自己从NotificationCenter的注册表中清除:
- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
轻松的
编辑
我想您还应该传递scroll视图,它是发送方,因为mainVC也包含该滚动视图。编辑代码
另一次编辑
在Defines.h文件中创建枚举define
enum {
TagSenderTypeFeed = 1,
TagSenderTypeImageDetail
};
typedef NSInteger TagSenderType;
在创建通知时,将适当的枚举值添加到通知的userInfo字典@“senderType”:@(TagSenderTypeFeed)
您考虑过使用通知而不是委托吗?回答得好。因此,如果我在TagsScrollView中进行广播,我如何区分哪个VC会做出反应?MainVC只知道FeedView,ImageDetailVC直接知道TagsScrollView。实际上,我可以递归地检查superview,看看它是否是特定VC的视图吗?这应该可以工作,这比我建议的更糟,不要偷懒,用正确的方法。问题是我的tagsScrollView不知道枚举类型是什么,因为我不总是能够直接指定它。在我的图表中,只有ImageDetailVC可以这样做。MainVC堆栈上的TagsScrollView无法知道这一点,除非MainVC通过多层让它知道这一点,这与我以前遇到的tagsPressedElegate模式类似。@tc。啊。。。有时,讽刺性的评论会产生非常多的积极影响。。。我现在知道了如何正确使用积木,以及如何避免保留循环。。。谢谢你,伙计
enum {
TagSenderTypeFeed = 1,
TagSenderTypeImageDetail
};
typedef NSInteger TagSenderType;