如何在.xib文件上创建的UIViewController中设置UITableView

时间:2012-07-13 06:57:23

标签: uitableview uiviewcontroller

我有一个这样的课程:

@interface ExerciseLogDetails : UIViewController<UIActionSheetDelegate, UITableViewDelegate, UITableViewDataSource> {

我试图显示一些元素,然后是UITextView。 UITextView元素在Interface Builder上创建。执行此代码时:

- (void)viewDidLoad {
self.tableView = [[UITableView alloc] initWithFrame:self.view.bounds       style:UITableViewStylePlain];
tableView.dataSource = self; 
tableView.delegate = self;
[self.view addSubview:self.tableView];
}

表格显示,但不是我在Interface Builder中配置的表格。它完全空白且未格式化。如何访问我的表并使用数据以程序方式填充它?

谢谢!

3 个答案:

答案 0 :(得分:18)

这个帖子的一些提示帮助我创建了这个。我将提供一些更完整的代码文件,以帮助其他人:

步骤1.在故事板或XIB中将UITableView拖到View Controller上。在我的例子中,我正在使用故事板。

步骤2:打开ViewController(在我的例子中只是DefaultViewController)并为UITableView添加两个委托: UITableViewDelegate UITableViewDataSource 。还为population和UITableView IBOutlet添加一个简单的数据源。

<强> DefaultViewController.h

#import <UIKit/UIKit.h>

@interface DetailViewController : UIViewController <UITableViewDelegate, UITableViewDataSource>

@property (strong, nonatomic) IBOutlet UITableView *tableView;
@property (strong, nonatomic) NSMutableArray *newsArray;

@end

步骤3:打开您的实施文件(DefaultViewController.m)并添加以下内容:

#import "DetailViewController.h"

@interface DetailViewController ()
- (void)configureView;
@end

@implementation DetailViewController

@synthesize newsArray;
@synthesize tableView;

#pragma mark - Managing the detail item

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.

    [self configureView];
}

- (void)configureView
{
    // Update the user interface for the detail item.
    self.newsArray = [[NSMutableArray alloc] initWithObjects:@"Hello World",@"Goodbye World", nil];
}



- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

#pragma mark UITableViewDelegate

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    // typically you need know which item the user has selected.
    // this method allows you to keep track of the selection

}

- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView
           editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
{

    return UITableViewCellEditingStyleDelete;
}

// This will tell your UITableView how many rows you wish to have in each section.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return [self.newsArray count];
}

// This will tell your UITableView what data to put in which cells in your table.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifer = @"CellIdentifier";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifer];

    // Using a cell identifier will allow your app to reuse cells as they come and go from the screen.
    if (cell == nil)
    {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifer];
    }

    // Deciding which data to put into this particular cell.
    // If it the first row, the data input will be "Data1" from the array.
    NSUInteger row = [indexPath row];
    cell.textLabel.text = [self.newsArray objectAtIndex:row];

    return cell;
}

@end

第4步:转到Storyboard或XIB并选择您的UITableView并将数据源委托出口拖到您的 DefaultViewController 上以连接它们。此外,您还需要将UITableView的引用插座连接到您在头文件中创建的 IBOutlet tableView 对象。

一旦完成,您应该能够运行它并且样本数据将会到位。

我希望这个以及该线程上的其他提示将帮助其他人在ViewController上从头开始设置UITableView。

答案 1 :(得分:12)

如果您在IB中配置了tableView,则不应该以编程方式创建一个,您应该创建@property (nonatomic, retain) IBOutlet UITableView *tableView;并将其连接到您在IB中配置的tableView。 尝试在tableView的中设置断点 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
委托方法来查看是否调用此方法。

来自Apple UITableView文档:

  

UITableView对象必须具有充当数据源的对象   以及充当代表的对象;通常这些对象是   应用程序委托,或者更常见的是自定义   UITableViewController对象。数据源必须采用   UITableViewDataSource协议和委托必须采用   UITableViewDelegate协议。数据源提供信息   UITableView需要构建表并管理数据模型   何时插入,删除或重新排序表的行。代表   提供表使用的单元格并执行其他任务,例如   管理配件视图和选择。

您可以看到,如果您没有将dataSource设置为tableView,则tableView将不知道如何显示以及显示什么,因此不会发生任何事情。
您可以通过调用tableView.dataSource = self;或IB从您的tableView拖动到文件的所有者(即必须实现UITableViewDataSource协议的viewController)来设置一个

UITableViewDataSource协议中有两种方法,您的dataSource 必须实施:

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

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

如果您不实施这些方法,您将收到编译器警告 如果实现UITableViewDelegate协议(如行/页眉/页脚高度,选择等等),您可以更好地控制tableView的外观......

来自Apple UITableView文档:

  

UITableView会覆盖UIView的layoutSubviews方法   只有在创建UITableView或的新实例时才调用reloadData   分配新数据源时。重新加载表视图会清除   当前状态,包括当前选择。但是,如果你   显式调用reloadData,它清除此状态和任何后续状态   对layoutSubviews的直接或间接调用不会触发重新加载。

创建tableView时或者在分配新的dataSource时(或当你明确地调用它时)调用ReloadData。)。
这是当tableView需要知道要显示什么(多少个部分?,有多少行?,以及要显示哪个单元?) - 所以这是调用numberOfRowsInSextion方法的时候。

答案 2 :(得分:2)

与Eyal一样,您不应该以编程方式在Interface Builder中创建UITableView。相反,在Interface Builder中创建一个并将其委托和数据源属性分配给IB中的文件所有者要容易得多。

完成此操作后,您无需以编程方式创建一个,并且不需要为tableview提供@property。 相反,您可以将UIViewController的类文件看起来像这样:

// YourViewController.h

#import <UIKit/UIKit.h>

@interface YourViewController : UIViewController <UITableViewDelegate, UITableViewDataSource>

@property (strong, nonatomic) NSArray *yourData;

@end

NSArray将包含您将以编程方式输入表格的数据。您可以像NSDictionary一样使用其他数据类,具体取决于您拥有的数据以及您希望它如何放在表格中。

// YourViewController.m

#import "YourViewController.h"

@implementation YourViewController
@synthesize yourData;

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Here you are creating some data to go in your table by inputting it as an array.
    // I just used some basic strings as an example.
    NSArray *array = [[NSArray alloc] initWithObjects:@"Data1", @"Data2", @"Data3", nil];
    // Copying the array you just created to your data array for use in your table.
    self.yourData = array;
}

- (void)viewDidUnload
{
    [super viewDidUnload];
    self.yourData = nil;
}

#pragma mark Table View Data Source Methods

// This will tell your UITableView how many rows you wish to have in each section.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return [self.yourData count];
}

// This will tell your UITableView what data to put in which cells in your table.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *CellIdentifer = @"CellIdentifier";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifer];

    // Using a cell identifier will allow your app to reuse cells as they come and go from the screen.
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifer];
    }

    // Deciding which data to put into this particular cell.
    // If it the first row, the data input will be "Data1" from the array.
    NSUInteger row = [indexPath row];
    cell.textLabel.text = [yourData objectAtIndex:row];

    return cell;
    }

@end

这应该只是创建一个简单的UITableView,其中包含您以编程方式输入的三个数据条目。

如果您有任何问题或疑问,请发表评论。 :)

希望这有帮助。