我写了一个自定义类TagsScrollView,它在滚动视图中显示标签。
当按下标签时,TagsScrollView依赖其代理来实现该做什么。几乎所有时间,这都涉及:
现在,这就是我的应用程序的结构:
虚线表示“有”关系。 MainVC有一个FeedView,它有一些FeedCellViews,而每个FeedCellViews都有一个TagsScrollView。
实线表示“推”关系。 ImageDetailVc被推送到MainVC的navController。
如何组织我的代码,以便可以优雅地将TagsScrollView的委托指向MainVC?
现在我已经定义了以下内容:
TagsScrollView.h
@protocol TagPressedDelegate<NSObject>
@required
- (void)tagPressed:(id)sender forQuery:(NSString *)query;
@end
FeedCellView.m
self.tagsScrollView.tagPressedDelegate = self.tagPressedDelegate
FeedView.m
self.cells[0].tagPressedDelegate = self.tagPressedDelegate
MainViewVC.m
self.feed.tagPressedDelegate = self
....
- (void)tagPressed...
我该如何避免这种模式?我能做得更好吗?我应该让TagsScrollViewDelegate扩展ScrollViewDelegate吗?
答案 0 :(得分:0)
你绝对可以做得更好,删除委托模式,使用块。
将基于块的属性添加到TagsScrollView .h文件
@property (copy, nonatomic) void (^tagPressedBlock)(id sender, NSString *query);
- (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。
在全局可见的地方定义通知名称,例如我建议在Prefix.pch文件中创建一个Defines.h文件和#including它。
无论如何,定义通知名称:
static 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];
}
易
修改
我想你也应该传递滚动视图,它是发送者,因为你的mainVC也包含滚动视图。编辑了代码
另一个编辑
在Defines.h文件中创建枚举定义
enum {
TagSenderTypeFeed = 1,
TagSenderTypeImageDetail
};
typedef NSInteger TagSenderType;
创建通知时,在通知的userInfo字典@"senderType" : @(TagSenderTypeFeed)