简单的iOS委托协议不适用于在视图控制器之间传递字符串

时间:2014-03-18 08:02:19

标签: ios iphone uitableview protocols delegation

我有一个看似简单的问题而且我无法弄清楚它为什么不起作用。

我有一个标签栏,主应用程序有一个表视图(时间轴),设置有一个。如果用户点击设置选项卡,他们就有机会选择一个主题,该主题只是另一个表格视图的形式,其中有多个单元格代表主题。

如果用户点击主题“黑色”,我希望标签栏中的其他表视图更改主题。

我并不担心主题的实施;我似乎在这里遇到了我的委托协议问题,尽管我遵循了我认为与我在我的应用程序中使用委托协议的其他用法相同的步骤。

这是主题的表格视图:

// .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显示我选择了“黑色”单元格,当委托发生在时间轴上时,它总是为零。

我正在使用带有自定义静态单元格的分组表格视图(据我所知,ThemesTableView上不需要cellForRowAtIndexPath,是吗?

更新:SelectThemesTableViewController

在storyboard中,SelectThemesTableViewController从“设置表视图控制器”选项卡中形成为segue(推送)。所以我在标签栏中有两个标签;第一个是时间轴,第二个是SettingsTableViewController。它嵌入在导航控制器中。 Table视图中的第一个单元格称为“主题”,单击它后,会有一个segue(推送)到SelectThemesTableViewController。我不是在准备任何地方,但是这让我想到也许我应该这样做?

我错过了什么?任何帮助都会非常感激!

3 个答案:

答案 0 :(得分:1)

为故事板更新了

好的,你没有提到你在使用故事板。你不应该在任何地方创建一个视图控制器

你的准备需要看起来像这样...

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

答案 1 :(得分:1)

当您在标签栏中使用两个控制器时,因此没有任何选项可以相互设置委托。相反,您可以在didSelectRow委托方法中的SelectThemesTableViewController中使用所选主题名称更新NSUserDefaults,当用户再次点击第一个选项卡时,只需检查TimelineTableViewController的viewWillAppear方法中的NSUserDefault值,并根据值更新UI。 / p>

  // .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");
        }
    }

答案 2 :(得分: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];
}