2014-03-18 6 views
0

У меня есть то, что кажется простой проблемой, и я просто не могу понять, почему он не работает.Простой протокол делегата iOS не работает с передачей строк между контроллерами просмотра

У меня есть панель вкладок с одним табличным видом (временная шкала) для основного приложения и одна для настроек. Если пользователь нажимает на вкладку настроек, у них есть возможность выбрать тему, которая находится только в виде другого представления таблицы с количеством ячеек, представляющих темы.

Если пользователь нажимает на тему «Черный», я хочу, чтобы другой Table View на панели вкладок менял тему.

Я не беспокоюсь о реализации темы; Кажется, у меня проблемы с протоколом моей делегации, хотя я следил за тем, что, по моему мнению, был тем же самым шагом, который я выполнил для других целей использования протоколов делегирования в моем приложении.

Вот мой Table View для темы:

// .h 
@class SelectThemesTableViewController; 

@protocol SelectThemesTableViewControllerDelegate <NSObject> 
- (void)selectThemesTableViewController:(SelectThemesTableViewController *)controller didSelectCell:(NSString *)selectedTheme; 
@end 

@interface SelectThemesTableViewController : UITableViewController 

@property (nonatomic, weak) id <SelectThemesTableViewControllerDelegate> delegate; 
@property (nonatomic, strong) NSString *selectedTheme; 
// .m 
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    UITableViewCell *selectedCell = [tableView cellForRowAtIndexPath:indexPath]; 
    self.selectedTheme = selectedCell.textLabel.text; 
    [self.delegate selectThemesTableViewController:self didSelectCell:self.selectedTheme]; 
    NSLog(@"The value of the selected cell is %@", self.selectedTheme); 
} 

В главном виде таблицы, где я хочу строка, которая передается:

// .h 
@property (nonatomic, strong) NSString *selectedTheme; 

// .m 
@interface TimelineTableViewController() <UITableViewDataSource, UITableViewDelegate, UISearchBarDelegate, NSFetchedResultsControllerDelegate, SelectThemesTableViewControllerDelegate> 

@end 

- (void)viewWillAppear:(BOOL)animated 
{ 
    [super viewWillAppear:animated]; 
    SelectThemesTableViewController *selectThemesTableViewController = [[SelectThemesTableViewController alloc] init]; 
    selectThemesTableViewController.delegate = self; 

    NSLog(@"What is this value %@", self.selectedTheme); 
    if ([self.selectedTheme isEqualToString:@"Black"]) 
    { 
     NSLog(@"The value is %@", self.selectedTheme); 

    } 
    else 
    { 
     NSLog(@"Nope"); 
    } 
} 

// Here in the viewWillAppear, I'm clearly setting the delegate but the self.selectedTheme is always nil. 

// Delegate method in the Timeline Table view: 

- (void)selectThemesTableViewController:(SelectThemesTableViewController *)controller didSelectCell:(NSString *)selectedTheme 
{ 
    self.selectedTheme = selectedTheme; 
    NSLog(@"String = %@", self.selectedTheme); 
    // The selectedTheme is always nil here 
} 

Я поставил контрольные точки в и последовал след, но в то время как в themeTableView NSLog показывает, что я выбираю «черную» ячейку, когда делегация происходит с временной шкалой, она всегда равна нулю.

Я использую сгруппированный вид таблицы с пользовательским статической ячейкой (так, насколько я понимаю, нет необходимости в cellForRowAtIndexPath на ThemesTableView, есть

Update: SelectThemesTableViewController

В раскадровке , SelectThemesTableViewController формируется как segue (push) с вкладки Control Table View Controller. Таким образом, у меня есть две вкладки на панели вкладок, первая - это временная шкала, а вторая - SettingsTableViewController. Она встроена в контроллер навигации. Первая ячейка в представлении «Таблица» называется «Темы», и, щелкнув по нему, есть segue (push) для SelectThemesTableViewController. Я не готовлюFo rSegue где угодно, но это заставляет меня думать, что, возможно, я должен быть?

Что мне не хватает? Любая помощь будет действительно оценена!

ответ

1

Поскольку вы используете оба двух контроллера в панели вкладок, поэтому нет никакой возможности установить делегат друг на друга.Вместо этого вы можете просто обновить NSUserDefaults с выбранным именем темы в SelectThemesTableViewController внутри метода делегата didSelectRow, и когда пользователь снова коснется первой вкладки, просто проверьте значение NSUserDefault в методе viewWillAppear TimelineTableViewController и обновите пользовательский интерфейс в соответствии с значением.

// .h 

    @interface SelectThemesTableViewController : UITableViewController 

    @property (nonatomic, strong) NSString *selectedTheme; 

    @end 

    // .m 
    - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
    { 
     UITableViewCell *selectedCell = [tableView cellForRowAtIndexPath:indexPath]; 
     self.selectedTheme = selectedCell.textLabel.text; 
     [[NSUserDefaults standardUserDefaults] setObject:self.selectedTheme forKey:@"Theme"]; 
     [[NSUserDefaults standardUserDefaults] synchronize]; 
     NSLog(@"The value of the selected cell is %@", self.selectedTheme); 
    } 

    ------------------------------------------------------------------------------------ 

    // .h 
    @property (nonatomic, strong) NSString *selectedTheme; 

    // .m 
    @interface TimelineTableViewController() <UITableViewDataSource, UITableViewDelegate, UISearchBarDelegate, NSFetchedResultsControllerDelegate> 

    @end 

    - (void)viewWillAppear:(BOOL)animated 
    { 
     [super viewWillAppear:animated]; 
     self.selectedTheme = [[NSUserDefaults standardUserDefaults] objectForKey:@"Theme"]; 
     NSLog(@"What is this value %@", self.selectedTheme); 
     if ([self.selectedTheme isEqualToString:@"Black"]) 
     { 
      NSLog(@"The value is %@", self.selectedTheme); 

     } 
     else 
     { 
      NSLog(@"Nope"); 
     } 
    } 
+0

Что абсолютно! Большое спасибо Сэму - если бы я мог проголосовать за него много раз, я бы это сделал. Используя этот метод, я могу обеспечить согласованность на протяжении всего жизненного цикла приложения, когда он закрывается и удаляется из многозадачности. Спасибо вам большое за это. Действительно большая помощь! – amitsbajaj

1

ОБНОВЛЕНО для раскадровки

OK вы не упомянули вы использовали раскадровку. Вы не должны создавать контроллер представления в любом месте

Ваших потребностей Подготовить смотреть что-то вроде этого ...

-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { 
    //The string needs to be whatever you've set up as the identifier in storyboard 

    if ([segue.identifier isEqualToString:@"themes"]) { 
     SelectThemesTableViewController * themeSelector = (SelectThemesTableViewController *) segue.destinationViewController; 
     themeSelector.delegate = self; 
    } 
} 
+0

Большое спасибо @Flexicoder и это на самом деле имеет большой смысл. Я внес изменения, но странно, что self.selectedTheme все еще ноль. Я собираюсь попробовать поиграть с ним, но я не уверен, что мне не хватает, хотя ваша рекомендация действительно имеет смысл ... какие-то мысли? – amitsbajaj

+0

Думайте, что 2 строки назначения должны быть в 'viewDidLoad', а не' viewWillAppear'. Вы переписываете значения каждый раз, когда возвращаетесь к просмотру – Flexicoder

+0

Спасибо @Flexicoder - попробовал это, но он, похоже, не работал. Однако я заметил, что метод delegate - (void) selectThemesTableViewController: (SelectThemesTableViewController *) controller didSelectCell: (NSString *) selectedTheme на временной шкале никогда не вызывается, потому что NSLog там (NSLog (@ "String =% @" , self.selectedTheme), никогда не будет уволен. Если я вызову этот метод из viewDidLoad или viewDIdAppear, он все равно будет равен нулю, но я всегда думал, что вам не нужно будет специально называть это ... он должен вообще сгореть? – amitsbajaj

0

Там нет ошибки в протоколе делегата. Это проблема с настройкой вашего делегата. Вы создаете отдельный контроллер представления и назначаете его делегату как self. При нажатии кнопки табуляции отображается не контроллер вида. Чтобы устранить этот метод установки делегата и добавить следующий код в свой SelectThemesTableViewController. Он должен работать.

// assume that first view controller in Tabbar view controller is TimelineTableViewController 
//Or else specify correct index of view controller when assigning to delegate. 
-(void)viewDidAppear:(BOOL)animated 
{ 
    [super viewDidAppear:animated]; 
    self.delegate = self.tabBarController.viewControllers[0]; 
} 
+0

Спасибо @rajath - с этим кодом в моем SelectThemesTableViewController, я получаю сообщение об ошибке с завершающим приложением из-за неотображенного исключения «NSInvalidArgumentException», причина: '- [UINavigationController selectThemesTableViewController: didSelectCell:]: непризнанный селектор отправлен в экземпляр Am I что-то не так с этим кодом? – amitsbajaj

+0

Уважаемый @rajath - большое спасибо за ваше время с ответом, а ответ ниже от sam сделал трюк. Я ценю ваши мысли и усилия с этим. – amitsbajaj

 Смежные вопросы

  • Нет связанных вопросов^_^