以编程方式向UIViewController添加UITableView

13
我正在将一个UIViewController加载到我的导航控制器层次结构中,其中将包含一些文本和一些图像。在底部,我想创建可展开和折叠的tableview。
首先,这个想法是否可能?如果是,如何添加它,并在哪里放置数据源和代理方法?
我可以只需创建一个TableViewController的独立子类,然后将其添加到我的ViewController作为子视图吗?

你不能将任何东西添加到视图控制器作为子视图,因为视图控制器不是视图,只有视图才有子视图。 - Peter Hosey
5个回答

20

是的,您可以创建一个UITableView,它的代理,数据源和父视图不一定是UITableViewController。由于UITableView是UIView,因此可以将其作为任何其他UIView的子视图添加。只要实现了所需的协议方法,任何NSObject都可以成为代理或数据源。

@interface MyViewController : UIViewController <UITableViewDelegate, UITableViewDataSource> 

事实上,根据我的经验,甚至很少有人使用UITableViewControllers。你上次想让你的表格视图占用整个可用空间是什么时候呢?通常情况下,我会创建一个普通的UIViewController,并将UITableView添加为其视图的子视图,除了其他子视图。


嘿@commanda,我是iOS开发的新手,正在寻找如何在UIViewController中正确实现插入UITableView和其他对象。无论如何,我偶然发现了这个问题,想知道是否有一些教程/源代码可以供我查看,以便我能够理解它的工作原理?谢谢! - gdubs

15
/************************************************/
/************* MyCustomController.m *************/
/************************************************/

@interface MyCustomController () <UITableViewDataSource, UITableViewDelegate>
@property (nonatomic, strong) UITableView *tableView;
@end

@implementation MyCustomController

- (id)initWithNibName:(NSString*)nibName bundle:(NSString*)bundleName
{
   self = [super initWitNibName:nibName bundle:bundleName];
   if (self)
   {
       self.tableView = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain];
       tableView.datasource = self; 
       tableView.delegate = self;
       [self.view addSubview:self.tableView];
   }

   return self;
}

#pragma mark - UITableViewDataSource Methods

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    // return number of rows
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    // return cell
}

#pragma mark - UITableViewDelegate Methods

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
{
    // handle table view selection
}

@end

11

非常简单,在像viewDidLoad这样的方法中:

UITableView *tableView = [[UITableView alloc] initWithFrame:self.view.bounds];
[self.view addSubview:tableView];

4
只需记住UITableViewController只是将表格视图设置为控制器的视图的UIViewController子类。
因此,当您想要拥有表格视图以及其他自定义UI元素防止您使用UITableViewController时,绝对可以并且经常使用。
通常我会选择在视图控制器的初始化方法或viewDidLoad方法中将其添加到其视图中。这将根据您是从NIB创建视图还是完全以编程方式创建而变化。
对于NIBs:
- (id)initWithNibName:(NSString*)nibName bundle:(NSBundle*)bundleName
{
   if ((self = [super initWitNibName:nibName bundle:bundleName]))
   {
       self.theTableView = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewWhateverStyleYouWantHere];
       theTableView.dataSource = self, theTableView.delegate = self;
       [self.view addSubview:theTableView];
       [theTableView release];
   }
}

然后您可以在viewDidLoad方法中设置tableview的框架。

个人建议在界面构建器中完成整个过程,这样您可以用更少的代码实现相同的结果,并且更易于维护。


我很好奇使用IB会导致"大量减少代码"。如果完全使用代码,initWithNibName:bundle: 将被更改为简单的 init - 但是还有其他什么变化吗? - Jason Moore
1
我认为“datasource”应该改为“dataSource”。 - Nate Flink

2

如果你和我一样,已经创建了一个UITableViewController,但意识到你为它做了很多工作,重新编写会很麻烦。那么,你可以按照以下步骤将UITableViewController作为子视图添加到UIViewController中。

UITableViewController* tableViewController = [[UITableViewController alloc] init];
[self.view addSubview:tableViewController.tableView];

以上所有其他答案都很好。我想为那些已经投入大量实现UITableViewController并感觉重构会很痛苦的人添加一些内容。


我甚至更喜欢这种方式——表控制器和视图控制器被很好地分开了。 - Tommz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接