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