如何访问另一个控制器/视图(iOS)

时间:2012-01-27 01:27:12

标签: objective-c ios cocoa-touch controller

我有三个独立的类,UIViewController(A)和两个UITableViewControllers(B和C)。

我将表B和C添加到A中。

[A.view addSubview:B.tableView];

[A.view addSubview:C.tableView];

现在我需要通过另一个表中的选择来更改/重新加载一个表。例如,在B中选择“肉”,然后C变成“鸡肉,猪肉......”,选择“水果”然后得到“苹果,番茄......”。

我的问题一般是如何访问另一个控制器/视图。我应该在B中的didSelectRowAtIndexPath中写什么来访问另一个控制器(A,C)?

3 个答案:

答案 0 :(得分:2)

我通常通过NSNotificationCenter执行此操作。在

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

使用NotificationCenter广播邮件。

[[NSNotificationCenter defaultCenter]postNotificationName:@"NotificationName" object:myObj];

在具有接收端的类上将其设置为在viewDidLoad或init方法中侦听此通知

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

在.m文件中声明您的方法

-(void)reloadTable:(NSNotification*)n {
[tableView reloadData];
}

请记住在dealloc方法中销毁对象时删除观察者 如果你正在使用ARC

- (void)dealloc {
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

如果您不使用ARC,请记得超级

- (void)dealloc {
    [[NSNotificationCenter defaultCenter] removeObserver:self];
    [super dealloc];
}

答案 1 :(得分:2)

您正在寻找delegation。将协议添加到B和C,让另一个实现它。

我很久以前写过sample code

在那里,CheckTableController可以通知ShowFavoritesTableController,因为第二个实现了第一个的委托协议。

答案 2 :(得分:0)

我认为最好的方法是使用一个,而不是使用三个独立的控制器。这个控制器将是UIViewController的子类,其.h文件应如下所示:

@interface MyController : UIViewController <UITableViewDataSource, UITableViewDelegate>
    UITableView *firstTableView;
    UITableView *secondTableView;
@end

现在,在.m文件中,将表格设置为:

- (id)init {
    if ((self = [super init])) {
        firstTableView = [[UITableView alloc] initWithFrame:/*desired frame*/ style:/*desired style*/];
        secondTableView = [[UITableView alloc] initWithFrame:/*desired frame*/ style:/*desired style*/];

        firstTableView.delegate = self;
        firstTableView.dataSource = self;

        secondTableView.delegate = self;
        secondTableView.dataSource = self;
    }
}

- (void)dealloc {
    [firstTableView release];
    [secondTableView release];
    [super dealloc];
}

然后,实现所需的UITableViewDataSource方法,如下所示:

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    if (tableView == firstTableView) {
        // Do something
    } else if (tableView == secondTableView) {
        // Do something else
    }
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
    }

    if (tableView == firstTableView) {
        // Configure the cell
    } else if (tableView == secondTableView) {
        // Configure the cell a different way
    }
}

最后,在didSelectRowAtIndexPath

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    if (tableView == firstTableView) {
        // Update something that is linked to the return values of secondTableView's dataSource methods
        [secondTableView reloadData];
    }
}

此方法可确保您的控制器自动获得正确的-viewDidLoad-viewWillAppear等。请记住,只是将视图控制器的视图添加为子视图意味着您的控制器将不会接收这些电话。