我有一个 UITableView,其委托(delegate)和数据源位于不同的文件中。点击一行时,在 tableView:didSelectRowAtIndexPath:
一个新的 View Controller 应该被压入堆栈。由于 NSObject 文件(包含 UITableView 委托(delegate)和数据源)没有 presentViewController:animated:completion:
我无法推送新的 View Controller 。
我想有两种方法可以解决这个问题。
选项 1:
将 TableView 的 View Controller ( RootViewController
) 的属性添加到 NSObject 文件,并在初始化对象时将该属性设置为等于 View Controller 。这样我就可以在 tableView:didSelectRowAtIndexPath:
中做到这一点
[self.rootVC presentViewController:detailVC animated:YES completion:nil];
选项 2:
我还可以向 NSObject 文件添加一个委托(delegate),它执行在 RootViewController
中更改 View Controller 的逻辑。 .
@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 的委托(delegate)和数据源放在那里。
两者都说它不在 View 层次结构中。 Warning: Attempt to present <DetailViewController 0x109123ff0> on <RootViewController: 0x10912aef0> whose view is not in the window hierarchy!
你更喜欢哪一个?或者我绝对不应该使用哪一个?我倾向于选择代表,因为第一个代表让我获得了另一个属性(property)/对象。
最佳答案
我可能会选择选项 2。这意味着您的委托(delegate)和数据源不需要仅仅为了呈现另一个 View Controller 而持有对 View Controller 的引用。这也是责任的额外分离 - 您的委托(delegate)/数据源仅负责管理 TableView 的数据,不在用户选择某些内容时执行 UI 功能/导航。
通过实现委托(delegate),您的YBMatchesTableViewDelegateAndDataSource
仍然是数据。它只是报告用户何时选择了一条数据。然后您的 View Controller 可以决定如何管理 View 来处理这个问题。
不过,我建议重命名您的 rowTapped
方法。我会让它更具描述性,并且根据您的设置,您可能想要传递一个参数,以便您的 viewcontroller 知道它需要显示什么内容。像这样的东西:
- (void)userDidSelectMatch:(YBMatch *)match;
或类似的东西(只是猜测你的数据结构),可能更有意义?
关于ios - 从 NSObject 子类呈现 View Controller ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21369497/