如何将变量从 UIViewController 传递给委托 UITableViewController [英] How to pass variable from UIViewController to delegate UITableViewController

查看:34
本文介绍了如何将变量从 UIViewController 传递给委托 UITableViewController的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm relatively new to iOS programming, so bear with me here. The requirement I'm working with is as follows:

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

Screen 1: User is shown a UITableView loaded with data, specifically City and State. The user taps on a selection and is taken to Screen 2.

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

Screen 2: The user is shown a "detailed" view of the item they selected for editing.

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

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

I have not had any issues implementing Screen 1. Here's how I passed the city and state values through to screen 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)创建 UITableViewControllers 并将它们加载到主 UIViewController(AdminCityView),如下所示:

In order to build Screen 2, however, I had to create UITableViewControllers for each UITableView (StateTable and SchoolTable) and load them in to the main UIViewController (AdminCityView), like so:

- (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进行操作(比如选择与变量匹配的行).

While I can get at the selectedState variable just fine in my UIViewController and my State table loads just fine in the UIView, I'm stuck at how to pass the selectedState variable from my UIViewController (AdminCityView) to the UITableViewController (StateTable) so that I can perform operations on StateTable with the variable (such as selecting the row that matches the variable).

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

I've been testing with NSLog on both AdminCityView and StateTable, and the variable is definitely only accessible from AdminCityView currently. I'm not sure if I need to pass it via code in AdminCityView, or if I should just go back to Screen 1 and somehow pass it to StateTable prior to navigating to AdminCityView.

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

I'm happy to post any additional code that might be helpful toward reaching an answer. Thanks!

推荐答案

有 3 种方法可以完成此任务,选择您的方法.

There are 3 ways to get this done, pick yours.

如果您使用的是故事板,则可以使用 segue 并完成它.从你的代码我只能猜测你不是,因为viewController:initWithNibName 那么就不需要了.

If you are using storyboard, you can just use a segue and be done with it. From your code i can only guess that you aren't, since viewController:initWithNibName would be unneccesary then.

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

So you are kind of stuck with the old ways, which turn out to be the best at some times...

您可以通过 NSNotificationCenter 使用通知.你使用

You could use a notification via the NSNotificationCenter. You subscribe your your stateTable to the notificationCenter using

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

observer 应该是 self,selector 是你必须实现的方法,它会在通知发送时被调用(你可以根据需要选择帽子名称),name 是通知的名称(随意选择),object 是你想要接收通知的对象(你可能不需要指定这个,除非你发送了很多通知).

where observer should be self, selector is a method you must implement that will get called when the notification is send (you can choose hat name as you wish), name is the name of the notification (choose as you like), and object is the object you want to receive Notifications from (you probably dont need to specify this one, unless you send a lot of Notifications).

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

Also you need to implement -(void)someMethodToCall: like this:

-(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 发送消息,这些消息可以携带有效载荷.您需要做的就是:

Your AdminCityView now can send messages to your stateTable, and those can carry payloads. All you need to do is:

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

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

Now Data from AdminCityView is transferred in a NSDictionary. Those things are really open-minded about stuff they accept, so you should be fine.

另一种方法是使用协议.

Another way is to use a protocol.

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

You can implement a protocol in AdminCityView like so:

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

就在头文件中的接口上面做,使用适合你的任何类型的数据.NSString 只是一个例子.

just do it above the interface in the header file, use whatever type of data suits you. NSString is just an example.

现在 stateController 需要符合该协议.在 stateController.h 中在界面后面添加:

Now stateController needs to conform to that protocol. in stateController.h add this behind the interface:

@interface stateController (UIViewController)<yourNameHereProtocol>{
}
-(void)someMethodToCall:(NSString *)theData;

现在 stateController 需要实现 someMethodToCall,在那里你处理数据,你就完成了一半.

Now stateController needs to implement someMethodToCall, where you process theData and you are halfway there.

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

Now, do this after creating dvController:

[dvController setDelegate:stateController];

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

Now, dvController can call the delegate method someMthodToCall:data in stateController, transmitting the data via the data-attribute.

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

Oh, and you really dont need two TableViewControllers, you can just conform the surrounding view to the UITableViewDataSource and TableViewDelegate protocols and handle all the different cases in the delegate methods. But thats for another post, i guess.

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

If you have any questions, please comment on this, and i will answer as good as i can. Also, i may have mixed up the denominators for your different Classes and such, feel free to change them as ist seems reasonable.

玩得开心

这篇关于如何将变量从 UIViewController 传递给委托 UITableViewController的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆