以编程方式将UITableViewController添加到当前视图

时间:2012-11-16 16:27:27

标签: iphone objective-c ios uitableview uiviewcontroller

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

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

@interface SecondViewController : UITableViewController{}

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

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

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

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

4 个答案:

答案 0 :(得分:4)

修改

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

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

原始答案

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

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

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

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

1)MainViewController(MVC)应该在属性中保留SecondViewController(SVC)实例,只要它是必需的。

2)SVC是UITableViewController的子类,因此默认情况下,它设置为dataSourcedelegateUITableView。这意味着您需要在UITableViewDataSource中实施UITableViewDelegateSVC方法,以便为您的表填充数据。假设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

答案 1 :(得分:0)

这是代码

1)添加DataSource并委派.h

2)在.m

中创建SOme代码
   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];

答案 2 :(得分:0)

在标题中,您必须告诉视图控制器符合UITableViewDataSource和UITableViewDelegate。在“UIViewController”

之后添加此项
<UITableViewDataSource, UITableViewDelegate>

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

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

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

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

此外,在您为表视图分配init时,您需要将其委托和数据源设置为当前类:

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

答案 3 :(得分: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构建后运行一个额外的方法 - 如果你google“presentViewController示例”,你可以采取一些例子查看以获取更多信息,或查看Apple Docs)。我知道保持它NULL将起作用,并且可能做你需要的。

一旦你完成了这一切,你就会回到现在的位置,在那里你会看到一堆空单元格(但你会以更传统的方式进入那里)。

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

之类的内容

设置UITableViewController还有很多东西比我在这篇文章中所涉及的更多,所以请查看YouTube上的一些教程或其他内容,因为他们已经花时间用更易消化的格式解释你需要的一切(当我第一次开始使用表格视图时,我发现this one非常有用,但是那里也有很多其他的。)