0

スクロール ビュー内にタグを表示するカスタム クラス、TagsScrollView を作成しました。

タグが押されると、TagsScrollView はそのデリゲートに依存して何をすべきかを実装します。ほとんどの場合、これには次のことが含まれます。

  1. タブのインデックスを別のインデックスに変更する
  2. TagsDetailVC を現在のナビゲーション コントローラーにプッシュします。

現在、これが私のアプリの構造です。

ここに画像の説明を入力

点線は「has」関係を示します。MainVC には FeedView があり、これにはいくつかの FeedCellView があり、それぞれに 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 を拡張させる必要がありますか?

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 ファイルを作成し、Prefix.pch ファイルに #include することをお勧めします。

とにかく、通知名を定義します。

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];
}

そして-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];
}

簡単

編集

メインVCにはスクロールビューも含まれているため、送信者であるスクロールビューも渡す必要があると思います。コードを編集しました

別の編集

Defines.h ファイルに列挙定義を作成します。

enum {
  TagSenderTypeFeed = 1,
  TagSenderTypeImageDetail
};
typedef NSInteger TagSenderType;

通知を作成するときに、適切な列挙値を通知の userInfo 辞書に追加します@"senderType" : @(TagSenderTypeFeed)

于 2013-03-22T22:52:44.260 に答える