15

我有这样的课:

@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 中配置的表格。它完全空白且未格式化。如何访问我的表并以编程方式填充数据?

谢谢!

4

3 回答 3

18

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

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

第 2 步:打开您的 ViewController(在我的情况下它只是 DefaultViewController)并为 UITableView 添加两个委托: UITableViewDelegateUITableViewDataSource。还为人口和 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。

于 2013-02-13T19:39:47.730 回答
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 构建表所需的信息,并在插入、删除或重新排序表的行时管理数据模型。委托提供表格使用的单元格并执行其他任务,例如管理附件视图和选择。

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

您的数据源必须实现 的UITableViewDataSource协议中有两种方法:

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

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

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

来自 Apple UITableView 文档:

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

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

于 2012-07-13T09:10:41.290 回答
2

就像 Eyal 所说,您不应该以编程方式和在 Interface Builder 中创建 UITableView。相反,只需在 Interface Builder 中创建一个并将其委托和数据源属性分配给 IB 中的 File's Owner 会容易得多。

完成此操作后,您无需以编程方式创建一个,也无需为 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,其中包含您以编程方式输入的三个数据条目。

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

希望这可以帮助。

于 2012-07-14T19:33:45.770 回答