来自NSObject子类的当前视图控制器

时间:2014-01-26 21:31:20

标签: ios objective-c

我有一个UITableView,其委托和数据源位于不同的文件中。点击一行时,在tableView:didSelectRowAtIndexPath:中,应该在堆栈上推送新的视图控制器。由于NSObject文件(包含UITableView委托和数据源)没有presentViewController:animated:completion:,因此我无法推送新的视图控制器。

我认为有两种方法可以解决这个问题。

选项1:

将表视图的视图控制器(RootViewController)的属性添加到NSObject文件,并在初始化对象时将该属性设置为等于视图控制器。这样我就可以在tableView:didSelectRowAtIndexPath:

中执行此操作
[self.rootVC presentViewController:detailVC animated:YES completion:nil];

选项2:

我还可以在NSObject文件中添加一个委托,该文件在RootViewController中执行更改视图控制器的逻辑。

@protocol YBMatchesTableViewDelegateAndDataSourceDelegate
@optional

-(void)rowTapped;

@end

@property(nonatomic,assign)id delegate;

tableView:didSelectRowAtIndexPath: [self.delegate rowTapped];。最后,在RootViewController中。

-(void)rowTapped {
    DetailViewController *detailVC = [[DetailViewController alloc] init];
    [self presentViewController:detailVC animated:YES completion:nil];
}

什么行不通:

  • [[RootViewController new] presentViewController:detailVC animated:YES completion:nil];
  • RootViewController进行子类化,并将tableview的委托和数据源放在那里。

两者都说它不在视图层次结构中。 Warning: Attempt to present <DetailViewController 0x109123ff0> on <RootViewController: 0x10912aef0> whose view is not in the window hierarchy!

您更喜欢哪一个?或者我应该使用哪一个?我倾向于去代理,因为第一个给我另一个属性/对象。

1 个答案:

答案 0 :(得分:1)

我可能会选择选项2 。这意味着您的委托和数据源不需要保持对viewcontroller的引用,只是为了它可以呈现另一个viewcontroller。这也是一个额外的责任分离 - 您的委托/数据源仅负责管理tableview的数据,用于在用户选择某些内容时执行UI功能/导航。

通过实施代理,您的YBMatchesTableViewDelegateAndDataSource仍然是数据。它只是报告用户何时选择了一段数据。然后,您的viewcontroller可以决定如何管理视图以处理它。

我建议您重命名rowTapped方法。我会使它更具描述性,并且根据您的设置,您可能希望传递一个参数,以便您的viewcontroller知道它需要显示哪些内容。类似的东西:

- (void)userDidSelectMatch:(YBMatch *)match;

或类似的东西(只是猜测你的数据结构),可能会更有意义吗?

相关问题