1

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

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

@interface SecondViewController : UITableViewController{}

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

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

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

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

4

4 回答 4

4

编辑

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

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

原始答案

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

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

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

配置这种通用模式的方法不止一种。在此示例中,我将坚持使用最简单的方法。

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

2) SVC 是UITableViewControllerso 默认的子类,它被设置为dataSourceand delegatefor it's UITableView。这意味着您需要为要填充数据的表实现UITableViewDataSourceUITableViewDelegate方法。SVC假设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
于 2012-11-16T17:17:57.570 回答
0

这是代码

1)添加数据源和委托.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];
于 2012-11-16T16:30:09.820 回答
0

在您的标题中,您必须告诉您的视图控制器符合 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];
于 2012-11-16T16:33:46.640 回答
0

好的,首先我想你在做什么[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 文档)。我确实知道保留它NULL会起作用,并且可能会满足您的需要。

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

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

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

于 2012-11-16T17:30:11.697 回答