iOS Master-Detail приложение: определение протокола, делегаты

В шаблоне приложения master-detail (используя ARC, раскадровки) в XCode 4.3.2 я пытаюсь изменить (точнее, заменить) представление подробностей, когда выбран элемент в представлении основной таблицы. Я пытаюсь реализовать делегаты / протоколы для этого.

Что меня смущает, так это то, какой класс должен реализовывать методы, определенные в протоколе, master или detail?

Наличие подробного представления, реализующего метод протокола, имеет смысл для меня, так как я буду толкать / выталкивать контроллеры представления в подробном представлении на основе выбора (передаваемого в виде строки из master через метод протокола).

Вот что я пробовал

1) Определен протокол в MasterViewController.h

@protocol MasterViewDelegate <NSObject>
- (void)masterSelectionChanged:(NSString *)selection;
@end
@interface MasterViewController:UIViewContoller
@property (nonatomic, weak) id <MasterViewDelegate> delegate

2) в MasterViewController.m

@synthesize delegate;
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    [delegate masterSelectionChanged:@"Some string based on indexPath.row"];
}

3) в DetailViewController.h

#import "MasterViewController.m"
@interface DetailViewController:UINavigationController <MasterViewDelegate>
@end

4) в DetailViewController.m

#pragma mark - MasterViewDelegate
- (void)masterSelectionChanged:(NSString *)selection
{
    NSLog(@"the selection is: %s", selection);
    // WIll push/pop view over here, may be perform segues based on selection
}

В этом процессе, после выбора строк в главной таблице, ничего не произошло. Без сбоев, без отображения журнала, без ошибок при сборке. Что я здесь пропустил?

1 ответ

Решение

Вам необходимо установить свойство делегата - в данный момент оно будет равно нулю, поэтому при отправке сообщений на него ничего не происходит. В шаблоне iPad вы можете сделать это следующим образом, в viewDidLoad вашего детального представления контроллера:

[super viewDidLoad];
if (self.splitViewController) // Means this won't be called if you use this code on iPhone too.
{
    // According to comments your master controller is embedded in a nav controller
    UINavigationController *nav = (UINavigationController*)[self.splitViewController.viewControllers objectAtIndex:0];
    // I am assuming it is the root view controller
    MasterViewController *master = (MasterViewController*)nav.rootViewController;
    // Finally set the delegate
    master.delegate = self;
}  
Другие вопросы по тегам