如何从 UIViewController 传递变量来委托 UITableViewController

Posted

技术标签:

【中文标题】如何从 UIViewController 传递变量来委托 UITableViewController【英文标题】:How to pass variable from UIViewController to delegate UITableViewController 【发布时间】:2012-12-27 21:54:18 【问题描述】:

我对 ios 编程比较陌生,所以请耐心等待。我正在处理的要求如下:

屏幕 1: 向用户显示加载数据的 UITableView,特别是城市和州。用户点击一个选择并且是 转到屏幕 2。

屏幕 2:向用户显示他们选择进行编辑的项目的“详细”视图。

城市字符串 (selectedCity) 放置在文本框中进行编辑 在 UITableView 中加载了一个 NSArray 状态。应根据从屏幕 1 传递的字符串 (selectedState) 在加载表中选择所选城市的状态。如果需要,用户可以在此处选择不同的状态。 第二个 UITableView 将包含一组与城市相关并从数据库中检索的学校。有一组单独的功能可用于管理此列表。

我在实施屏幕 1 时没有遇到任何问题。以下是我将城市和州值传递到屏幕 2 的方式:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 

    //Get the City
    self.checkedCellIndex = indexPath.row;
    FSCity *selectedCity = [CityList objectAtIndex:indexPath.row];
    NSString *cityName = selectedCity.name;
    NSString *stateName = selectedCity.state;

    AdminCityView *dvController = [[AdminCityView alloc] initWithNibName:@"AdminCityView" bundle:[NSBundle mainBundle]];
    dvController.selectedCity = cityName;
    dvController.selectedState = stateName;

    [self.navigationController pushViewController:dvController animated:YES];

    dvController = nil;

然而,为了构建 Screen 2,我必须为每个 UITableView(StateTable 和 SchoolTable)创建 UITableViewController,并将它们加载到主 UIViewController(AdminCityView),如下所示:

- (void)viewDidLoad

    [super viewDidLoad];

    txtCity.text = selectedCity;

    if (stateController == nil) 
        stateController = [[StateTable alloc] init];
    
    if (schoolController == nil) 
        schoolController = [[SchoolTable alloc] init];
    
    [tblState setDataSource:stateController];
    [tblSchool setDataSource:schoolController];

    [tblState setDelegate:stateController];
    [tblSchool setDelegate:schoolController];
    stateController.view = stateController.tableView;
    schoolController.view = schoolController.tableView; 

虽然我可以在 UIViewController 中很好地获取 selectedState 变量,并且我的 State 表在 UIView 中加载也很好,但我被困在如何将 selectedState 变量从我的 UIViewController (AdminCityView) 传递到 UITableViewController (StateTable)这样我就可以使用变量对StateTable执行操作(例如选择与变量匹配的行)。

我一直在 AdminCityView 和 StateTable 上使用 NSLog 进行测试,并且该变量目前肯定只能从 AdminCityView 访问。我不确定是否需要通过 AdminCityView 中的代码传递它,或者我是否应该返回屏幕 1 并在导航到 AdminCityView 之前以某种方式将其传递给 StateTable。

我很高兴发布任何可能有助于获得答案的其他代码。谢谢!

【问题讨论】:

为什么要使用两个表视图。我会使用一个带有标题的表格视图和两个部分用于不同的选择。 出于用户体验目的。在视图(屏幕)1 上,用户将选择他们想要编辑的城市。屏幕 2 将允许他们编辑该城市的名称、它所属的州,并添加/编辑/查看该城市内的学校列表。应用程序中还有其他几个类似的数据结构,所以一旦我让这个“模型”工作,我想重复它来处理那些其他数据集(再次,为了一致的用户体验)。 为什么不能为 selectedState 使用全局字符串变量。然后不需要传递值。您可以直接从 UITableViewController 访问该变量.. 【参考方案1】:

有 3 种方法可以完成这项工作,选择你自己的。

如果您使用故事板,您可以只使用 segue 并完成它。 从您的代码中,我只能猜测您不是,因为 viewController:initWithNibName 将是不必要的。

所以你有点坚持旧的方式,有时结果是最好的......

您可以通过 NSNotificationCenter 使用通知。 您将 stateTable 订阅到 notificationCenter 使用

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(someMethodToCall:) name:@"someName" object:nil];

其中观察者应该是自我,选择器是您必须实现的方法,当通知发送时将被调用(您可以根据需要选择帽子名称),名称是通知的名称(随意选择),并且 object 是您希望从中接收通知的对象(您可能不需要指定这个,除非您发送了很多通知)。

你还需要实现 -(void)someMethodToCall: 像这样:

-(void)someMethodToCall:(NSNotification *)notification
    NSDictionary *dic = notification.userInfo;
    //you will store all the data you want transferred in this, as you will see.
    //use it as you like

您的 AdminCityView 现在可以向您的 stateTable 发送消息,并且这些消息可以携带有效负载。您需要做的就是:

[self postNotificationName:@"theNameYouChoseAbove" object:yourFirstViewController  userInfo:someDictionaryThatHoldsYourValues];

现在来自 AdminCityView 的数据在 NSDictionary 中传输。那些东西对他们接受的东西真的很开放,所以你应该没问题。

另一种方法是使用协议。

您可以像这样在 AdminCityView 中实现协议:

@protocol yourNameHereProtocol
-(void)methodToCall:(NSString*)theData;
@end

只需在头文件中的界面上方进行,使用适合您的任何类型的数据。 NSString 只是一个例子。

现在 stateController 需要符合该协议。在 stateController.h 的接口后面添加这个:

@interface stateController (UIViewController)<yourNameHereProtocol>

-(void)someMethodToCall:(NSString *)theData;

现在 stateController 需要实现 someMethodToCall,你在其中处理 theData 并且你已经完成了一半。

现在,在创建 dvController 之后执行此操作:

[dvController setDelegate:stateController];

现在dvController可以调用stateController中的委托方法someMthodToCall:data,通过data-attribute传递数据。

哦,你真的不需要两个 TableViewControllers,你可以让周围的视图符合 UITableViewDataSource 和 TableViewDelegate 协议,并在委托方法中处理所有不同的情况。但那是另一篇文章,我猜。

如果您有任何问题,请对此发表评论,我会尽力回答。 另外,我可能混淆了您不同班级的分母等,请随意更改它们,因为这似乎是合理的。

玩得开心

【讨论】:

以上是关于如何从 UIViewController 传递变量来委托 UITableViewController的主要内容,如果未能解决你的问题,请参考以下文章

从 UIViewController 将变量传递给自定义 UITableViewCell

将变量从 customCell.xib 的按钮传递到另一个 UIViewController

将数据从 UIViewControllerRepresentable 传递给 UIViewController

iOS:如何从 UIViewController 通知 appDelegate

从 UIVIewController 向 SKScene 传递数据

Swift - 如何将数据从 UITableViewCell 类传递到 UIViewController