0

我编写了一个自定义类,TagsScrollView,它在滚动视图中显示标签。

当标签被按下时,TagsScrollView 依靠它的委托来实现做什么。几乎所有时候,这都涉及:

  1. 将选项卡索引更改为另一个索引
  2. 将 TagsDetailVC 推送到当前导航控制器。

现在,这就是我的应用程序的结构:

在此处输入图像描述

虚线表示“有”关系。MainVC 有一个 FeedView,它有几个 FeedCellView,每个 FeedCellView 又都有一个 TagsScrollView。

实线表示“推”关系。ImageDetailVc 被推送到 MainVC 的 navController 上。

如何组织我的代码,以便可以优雅地指向 MainVC 的 TagsScrollView 的委托?

现在我已经定义了以下内容:

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

主视图VC.m

self.feed.tagPressedDelegate = self
....

- (void)tagPressed... 

我怎样才能避免这种模式?我能做些什么更好?我应该让 TagsScrollViewDelegate 扩展 ScrollViewDelegate 吗?

4

1 回答 1

0

您绝对可以做得更好,删除委托模式,使用块。

将基于块的属性添加到您的 TagsScrollView .h 文件

@property (copy, nonatomic) void (^tagPressedBlock)(id sender, NSString *query);

在 .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 文件并将其#include 到您的 Prefix.pch 文件中。

无论如何,定义通知名称:

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作为观察者添加到该通知中:

主VC.m

- (void)viewDidLoad {
  [super viewDidLoad];
  [[NSNotificationCenter defaultCenter] addObserver:self
                                           selector:@selector(tagPressed:)
                                               name:TagPressedNotification
                                             object:nil];
}

-tagPressed:并在您的 MainVC 中实现方法

- (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)

于 2013-03-22T22:52:44.260 回答