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

时间:2012-12-27 21:54:19

标签: objective-c uiviewcontroller nsmutablearray uitableview

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

  

屏幕1:用户会看到一个载有数据的UITableView,特别是城市和州。用户点击选择即可   拍摄到屏幕2。

     

屏幕2:用户会看到"详细信息"查看他们选择进行编辑的项目。

     
      
  • 城市字符串( selectedCity )放置在文本框中进行编辑
  •   
  • NSArray of States加载到UITableView中。应根据从屏幕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)创建UITableViewControllers并将它们加载到主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变量并且我的状态表在UIView中加载得很好,但我仍然坚持如何将selectedState变量从我的UIViewController(AdminCityView)传递给UITableViewController( StateTable)以便我可以使用变量对StateTable执行操作(例如选择与变量匹配的行)。

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

我很乐意发布可能有助于找到答案的任何其他代码。谢谢!

1 个答案:

答案 0 :(得分:1)

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

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

所以你有点坚持旧的方式,有时候会变得最好......

您可以通过NSNotificationCenter使用通知。 您使用

将stateTable订阅到notificationCenter
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(someMethodToCall:) name:@"someName" object:nil];

其中observer应该是self,selector是一个你必须实现的方法,它会在发送通知时被调用(你可以根据需要选择帽子名称),name是通知的名称(根据你的意愿选择),和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,你在那里处理数据并且你已经到了一半。

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

[dvController setDelegate:stateController];

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

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

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

玩得开心