2013-03-22 91 views
0

我寫了一個自定義類TagsScrollView,它在滾動視圖中顯示標籤。通過多個層次傳遞委託

當按下標籤時,TagsScrollView依賴其委託來實現要執行的操作。幾乎所有的時間,這包括:

  1. 更改標籤索引移動到另一個指標
  2. 推TagsDetailVC當前的導航控制器。

現在,這是我的應用程序是如何構成的:

enter image description here

虛線表示 「有」 的關係。 MainVC有一個FeedView,它有幾個FeedCellView,每個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嗎?

+3

你有沒有考慮使用通知而不是委託? – 2013-03-22 22:49:15

回答

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文件中。

無論如何,定義通知名稱:

static NSString *const TagPressedNotification = @"TagPressedNotification";

下一步在執行-tagPressed:發佈通知和封裝有價值的信息到用戶信息詞典:

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

添加,不要忘記清理自己了通知中心的寄存器:

- (void)dealloc { 
    [[NSNotificationCenter defaultCenter] removeObserver:self]; 
} 

容易

編輯

我想你也應該傳遞滾動視圖,這是發件人,因爲你的mainVC也包含該滾動視圖。編輯代碼

另一個編輯

創建枚舉在Defines.h定義文件

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

當創建一個通知加入適當枚舉值到您的通知的用戶信息字典@"senderType" : @(TagSenderTypeFeed)

+0

嘿,好的答案。所以如果我在TagsScrollView中進行廣播,我該如何區分哪個VC會做出反應? MainVC只知道FeedView,而ImageDetailVC直接瞭解TagsScrollView。 – disappearedng 2013-03-22 23:18:55

+0

mkay,編輯答案 – Eugene 2013-03-22 23:26:31

+0

實際上,我可以遞歸地檢查超級視圖,看看它是否是一個特定的VC視圖?那應該可以工作 – disappearedng 2013-03-22 23:30:43