【问题标题】:Add UITableViewController to Current View Programmatically以编程方式将 UITableViewController 添加到当前视图
【发布时间】:2012-11-16 16:27:27
【问题描述】:

我需要从现有视图中以编程方式显示 UITableViewController。

我有一个 MyAppViewController,它的视图上的按钮应该打开一个新的 UITableViewController。但到目前为止,我似乎无法让它发挥作用。这是 UITableViewController 的样子:

@interface SecondViewController : UITableViewController{}

在主视图上,我使用以下命令添加表视图控制器:

SecondViewController vc2 = [[SecondViewController alloc] init];
vc2.view.frame = {...}
[self.view addSubview: vc2.view];

这就是我通常添加简单视图控制器的方式,所以我认为 UITableViewController 是一样的。

我得到的结果是整个屏幕上的单元格都是空的。这是因为未设置委托,我假设,但我会在哪里设置呢?所以我的困惑是 UITableViewController 视图控制器上的委托设置器并从主视图控制器的视图中正确显示 UITableViewController。

【问题讨论】:

  • 有点糊涂,你问的是如何添加UITableViewController或者如何为UITableView设置单元格内容?
  • 如何添加 UITableViewController...如果我成功了,我想我将能够处理单元格内容
  • @Vad:你在用故事板吗?
  • 不,如果可能,我希望以编程方式实现
  • @Vad:即使它在情节提要中,您仍然可以以编程方式进行操作。我问是因为如果它们是情节提要上的视图与您有 .nib 与控制器完全以编程方式设置,语法会有所不同。

标签: iphone objective-c ios uitableview uiviewcontroller


【解决方案1】:

编辑

这个答案已经过时了。将视图控制器的视图添加为另一个视图控制器的子视图的正确方法是实现容器视图控制器。

https://developer.apple.com/library/ios/featuredarticles/ViewControllerPGforiPhoneOS/CreatingCustomContainerViewControllers/CreatingCustomContainerViewControllers.html

原始答案

你的模式有点与众不同。执行您所描述的操作的最常见方法是初始化并呈现 SecondViewController。如果这确实是您想要的,我强烈建议您仔细阅读 Apple 的文档,了解如何创建、自定义和呈现 UIViewControllerUITableViewController

如果您知道所有这些并且真的想要做一些自定义的事情,那么请继续阅读。

相反,您正在创建 SecondViewController 的实例,而不是呈现它,而是将其视图添加到当前视图控制器视图中。如果您知道自己想要完成什么并且这实际上是您想要的结果,那么就去做吧。

配置这种通用模式的方法不止一种。在这个例子中我会坚持最简单的方式。

1) MainViewController (MVC) 应该在需要时将 SecondViewController (SVC) 实例保留在属性中。

2) SVC 是UITableViewController 的子类,因此默认设置为dataSourcedelegate,因为它是UITableView。这意味着您需要在SVC 中实现UITableViewDataSourceUITableViewDelegate 方法,以便为您的表填充数据。假设MVC 知道需要将哪些数据放入表中,它应该将其传递给SVC。最简单的方法是在SVC 上定义一个属性,该属性可以在初始化时在MVC 中设置。

3) 假设有一种方法可以在表格呈现后将其关闭,您会希望 MVC 这样做。基本上,MVC 会将SVC 的视图从其父视图中移除,然后将SVC 属性设置为nil。

这里有一些快速的伪代码。我写了最低限度的例子。

// MainViewController.h
//
#import "SecondViewController.h"

@interface MainViewController : UIViewController
@property (nonatomic, strong) SecondViewController *svc;
@end

// MainViewController.m
//
#import "MainViewController.h"

@implementation MainViewController

// init and configure views w/ init, loadView, viewDidLoad, etc

// present SecondViewController
- (void)presentSecondViewController:(id)sender {
    self.svc = [[SecondViewController alloc] init];
    // this example uses an array as the SVC data
    self.svc.tableData = @[@"first", @"second", @"third", @"fourth"];
    self.svc.view.frame = self.view.bounds;
    [self.view addSubview:self.svc.view];
}

// dismiss SecondViewController
- (void)dismissSecondViewController:(id)sender {
    if (self.svc) {
        [self.svc.view removeFromSuperview];
        self.svc = nil;
    }
}

// SecondViewController.h
//
@interface SecondViewController : UITableViewController
@property (nonatomic, strong) NSArray *tableData;
@end

// SecondViewController.m
//
@implementation SecondViewController

// init and configure views w/ init, loadView, viewDidLoad, etc

// override tableData getter to create empty array if nil
- (NSArray *)tableData
{
    if (!tableData) {
        _tableData = @[];
    }
    return _tableData;
}

// override tableData setter to reload tableView
- (void)setTableData:(NSArray *)tableData
{
    _tableData = tableData;
    [self.tableView reloadData];
}

// implement UITableViewDelegate and UITableViewDataSource methods using
// the self.tableData array

【讨论】:

  • 你是对的。我不需要@interface SecondViewController : UIViewController 正如许多人所说的那样。
【解决方案2】:

在您的标题中,您必须告诉您的视图控制器符合 UITableViewDataSource 和 UITableViewDelegate。在“UIViewController”之后添加这个

<UITableViewDataSource, UITableViewDelegate>

然后在您的实现文件中,您需要为表添加委托和数据源方法,例如:

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

您可以在 UITableViewDataSourceUITableViewDelegate 类参考中找到完整列表。

此外,在您分配初始化表视图的位置,您需要将其委托和数据源设置为当前类:

[myTableView setDelegate:self];
[myTableView setDataSource:self];

【讨论】:

  • 考虑到我的 SecondViewController 已经是 UITableViewController,我还需要 吗?
【解决方案3】:

好的,首先我认为您正在使用 [self.view addSubview] 将项目中的所有视图堆积到同一个视图控制器中,更传统的方法是在完成后关闭视图控制器它并自己创建新的视图控制器。您正在做的堆积是非常规的,我认为这会误导将来尝试查看您的代码的人。此外,如果您真的开始尝试进行标准导航,那将是一件令人头疼的事情。此外,它看起来像是一场内存管理的噩梦(尽管我承认我对此仍然有些模糊,所以我不知道 ARC 是否会为你清理它,如果你真的在使用 ARC)。也就是说,在某些情况下您可能会尝试这样做 - 但如果您不确定,那意味着这不是您想要做的(如果这是您想要做的,请查看 XJones 的回答)。我认为您正在寻找的是presentViewController - 这是摆脱不需要的控制器并用新控制器替换它的更传统方法。摆脱

vc2.view.frame = {...}
[self.view addSubview: vc2.view];

替换成

[self presentViewController:vc2 animated:/*YES or NO, try them both and use whichever one you like better*/ completion:NULL];

注意:我不完全确定 completion 做了什么(我认为它可能允许您在构建 vc2 后运行一个额外的方法 - 如果您搜索“presentViewController 示例”,您可以查看一些示例在获取更多信息,或查看Apple Docs)。我知道保留它NULL 会起作用,并且可能会满足您的需求。

完成所有这些操作后,您将立即回到您现在所在的位置,您将看到上面有一堆空单元格的视图(但您将以更传统的方式到达那里)。

从这里开始,您需要向您的 SecondViewController.m 添加一些代码来告诉它您想要显示的内容。通常,您将有一个字符串数组,并且您希望表格的第一个单元格有一个标签,显示该数组中的第一个字符串,第二个单元格显示第二个字符串,依此类推。为此,您将拥有类似cell.textLabel = [myArray objectAtIndex:indexPath.row]; 的信息。

设置 UITableViewController 的内容比我在这篇文章中所能介绍的要多得多,因此请查看 YouTube 上的一些教程或其他内容,因为它们已经花时间以更易于理解的格式解释您需要的所有内容(当我第一次开始使用表格视图时,我发现this one 非常有帮助,但那里也有很多其他的)。

【讨论】:

    【解决方案4】:

    这是代码

    1)添加DataSource和Delegate.h

    2)在.m中创建一些代码

       thisTableView = [[UITableView alloc] initWithFrame:CGRectMake(6.5, 60,      self.view.bounds.size.width - 10, 350) style:UITableViewStylePlain];
    
        [thisTableView setBounces:NO];
        thisTableView.backgroundColor = [UIColor whiteColor];
    
    thisTableView.delegate = self;
    thisTableView.dataSource = self;
    [self.view addSubview:thisTableView];
        [thisTableView release];
    

    【讨论】:

    • 这个tableview怎么知道它属于SecondViewController?
    • @Vad 实际上你应该清楚你的要求,因为你说你需要在按钮点击时创建TableView。所以在这里你可以做的是,正如我提到的如何在 SecondViewController 中创建 tableView并在按钮上单击导航到该 secondViewController 或显示该视图模态。因此,您需要将该代码放在 Second ViewController 中,并且您必须在这些方法中编写一些代码才能正常工作。
    • 对不起,我的 SecondViewController 已经是一个 UITableViewController。出于某些原因,我更喜欢保持这种状态。基于此,您的第一个代码是否有效: UIViewController 还是我应该将其保留为 UITableViewController
    • @Vad 据我所知,如果您创建继承自 UIViewController 的 SecondViewController。您可以为代码提供更多灵活性
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-08-22
    • 2017-10-09
    • 2017-06-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多