简体   繁体   English

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

[英]Simple iOS Delegate Protocol Not Working With Passing Strings Between View Controllers

I have what appears to be a simple problem and I just cannot figure out why it isn't working. 我有一个似乎是一个简单的问题,我只是无法弄清楚它为什么不起作用。

I have a tab bar with one table view (Timeline) for the main app and one for the settings. 我有一个标签栏,主应用程序有一个表视图(时间轴),一个用于设置。 If the user clicks on the settings tab, they have the chance of selecting a theme which is just in the form of another table view with a number of cells representing themes. 如果用户点击设置选项卡,他们就有机会选择一个主题,该主题只是另一个表格视图的形式,其中有多个单元格代表主题。

If the user clicks on theme "Black", I want the other Table View in the Tab bar to change theme. 如果用户点击主题“黑色”,我希望标签栏中的其他表格视图更改主题。

I'm not worried about the theme implementation; 我并不担心主题的实施; I seem to be having issues with my delegation protocol here even though I have followed what I believe to be the same steps that I followed for other uses of delegation protocols in my app. 我似乎在这里遇到了我的委托协议问题,尽管我遵循了我认为与我在我的应用程序中使用委托协议的其他用法相同的步骤。

Here's my Table View for the Themes: 这是主题的表格视图:

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

In the main table view where I want the string to be passed: 在主表视图中我希望传递字符串:

// .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 
}

I have put breakpoints in and followed the trace, but while in the themeTableView, the NSLog shows me selecting the "black" cell, when the delegation happens to the Timeline, it's always nil. 我已经在跟踪中添加了断点,但是在themeTableView中,NSLog显示我选择了“黑色”单元格,当委托发生在时间轴上时,它总是为零。

I'm using a grouped table view with a custom static cell (so as far as I understand, there's no need for cellForRowAtIndexPath on the ThemesTableView, is there? 我正在使用带有自定义静态单元格的分组表格视图(据我所知,在ThemesTableView上不需要cellForRowAtIndexPath,是吗?

Update: SelectThemesTableViewController 更新:SelectThemesTableViewController

In storyboard, SelectThemesTableViewController is formed as a segue (push) from the Settings Table View Controller tab. 在故事板中,SelectThemesTableViewController从“设置表视图控制器”选项卡中形成为segue(推送)。 So I have two tabs in a tab bar; 所以我在标签栏中有两个标签; the first is the Timeline and the second is SettingsTableViewController. 第一个是时间轴,第二个是SettingsTableViewController。 This is embedded in a navigation controller. 它嵌入在导航控制器中。 The first cell in the Table view is called "Themes" and upon clicking on that, there is a segue (push) to the SelectThemesTableViewController. Table视图中的第一个单元格称为“主题”,单击它后,会有一个segue(推送)到SelectThemesTableViewController。 I'm not preparingForSegue anywhere, but this gets me thinking that perhaps I should be? 我不是在准备任何地方,但这让我想到也许我应该这样做?

What am I missing? 我错过了什么? Any assistance would be really appreciated! 任何帮助将非常感谢!

UPDATED for storyboard 更新了故事板

OK you hadn't mentioned you were using storyboards. 好的,你没有提到你在使用故事板。 You shouldn't be creating a view controller anywhere 您不应该在任何地方创建视图控制器

Your Prepare needs to look something like this... 你的准备需要看起来像这样......

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

As you are using both two controllers in tab bar, So there is no any option to set delegate to each other. 由于您在标签栏中使用了两个控制器,因此没有任何选项可以相互设置委托。 Instead what you can do is just update the NSUserDefaults with the selected theme name in SelectThemesTableViewController inside didSelectRow delegate method and when user will again tap on first tab just check the NSUserDefault value in viewWillAppear method of TimelineTableViewController and update the UI as per the value. 相反,您可以在didSelectRow委托方法中的SelectThemesTableViewController中使用所选主题名称更新NSUserDefaults,当用户再次点击第一个选项卡时,只需检查TimelineTableViewController的viewWillAppear方法中的NSUserDefault值,并根据值更新UI。

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

There is no mistake in delegate protocol. 代表协议没有错误。 It is problem with your delegate setting. 您的代理设置存在问题。 You are creating separate view controller and assigning its delegate as self. 您正在创建单独的视图控制器并将其委托指定为self。 It is not the view controller which is shown, when setting tab button is pressed. 按下设置选项卡按钮时,不显示视图控制器。 To resolve this delegate setting method and add following code in your SelectThemesTableViewController. 要解决此委托设置方法并在SelectThemesTableViewController中添加以下代码。 It should work. 它应该工作。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM