当其父级不是 UITableViewController 时,UITableView 不显示内容

Posted

技术标签:

【中文标题】当其父级不是 UITableViewController 时,UITableView 不显示内容【英文标题】:UITableView not displaying content when its parent is not UITableViewController 【发布时间】:2013-12-24 16:52:37 【问题描述】:

在 XCode 5 中,当您添加一个 UITableViewController 具有多个包含标签等的原型单元格时,会显示内容,因为 UITableViewController 会自动设置数据表视图的源和委托,并向其发送 reloadData 消息。

ios Developer Library - Basics of Table View Creation

但是当您将 UITableView 拖到 UIViewController 时,我相信您必须创建类似于下面的默认方法的实例方法,以便重新加载和制作内容可见。

我的问题是,如何将 UITableView 定位在 UIViewController 中的某个位置,并设置其数据源和委托,并重新加载并正确显示其内容?

这是 UITableViewController 的默认代码:

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView

    // Return the number of sections.
    return 0;


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

    // Return the number of rows in the section.
    return 0;


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

    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];

    // Configure the cell...

    return cell;

这是我的代码,它适用于 UITableViewController 但不适用于它包含的 UITableView 的 UIViewController:

...

@property (nonatomic, strong) NSArray *menuItems;

...

- (void) viewDidLoad 

    [super viewDidLoad];
    self.menuItems = @[@"rowOne", @"rowTwo", @"rowThree", @"rowFour"];


...

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView

    // Return the number of sections.
    return 1;


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

    // Return the number of rows in the section.
    return [self.menuItems count];


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

    NSString *CellIdentifier = [self.menuItems objectAtIndex:indexPath.row];
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];

    return cell;

【问题讨论】:

您是否将代理和数据源属性绑定到您的视图控制器? 【参考方案1】:

如果您的单元格不存在,则在您的代码中创建您的单元格?并将单元格标识符设为静态。

如果 cellForRowAtINdexPath 中不存在单元格,则应创建单元格,如下所示:

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

    static NSString *CellIdentifier = @"CellIdentifier";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
     if(cell == nil)
       
        //Create your cell
        cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
      


     //Configure your cell

    return cell;

【讨论】:

您实现的方式,CellIdentifier 不正确,因为您从 menuItems 数组引用对象而不定义静态 NSString 单元格标识符。 哦,是的。感谢您的关注。实际上我在复制问题时忘记删除它。查看我编辑的答案。【参考方案2】:

您可以通过几种方式设置数据源和委托。如果您将表格视图添加到情节提要中的视图控制器,只需控制从表格视图拖动到视图控制器并选择委托并再次执行并选择数据源。 您还可以在 viewDidLoad 中创建插座并在视图控制器中执行以下操作:

self.tableView.dataSource = self;
self.tableView.delegate = self;

另一种方法是在代码中创建表格视图并将其添加到您的视图控制器视图中。你可以在 viewDidLoad 中这样做:

tableView = [[UITableView alloc] initWithFrame:CGRectMake(TABLE_VIEW_FRAME) style:UITableViewStylePlain];
tableView.dataSource = self;
tableView.delegate = self;

[self.view addSubview:tableView];

如果您想重新加载数据,只需调用:

[self.tableView reloadData];

希望对您有所帮助。

【讨论】:

绝对精彩。我通过右键单击从 UITableView 拖动到 UIViewController 创建了一个插座来设置数据源并在情节提要中委托,它工作正常。我正在以非常快的速度学习 XCode。感谢您向我展示如何通过代码和使用情节提要来做到这一点。【参考方案3】:

确保实现 UITableViewDelegateUITableViewDataSource 协议并将它们设置在 initWithNibNameinitWithCoder 初始化程序中。

这是您的 .h 文件的外观:

@interface TestViewController : UIViewController <UITableViewDelegate, UITableViewDataSource>

这是您需要在 .m 文件中执行的操作:

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil 
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) 
        self.tableView.delegate = self;
        self.tableView.dataSource = self;
    
    return self;

如果您使用storyboards,请使用initWithCode,如下所示:

- (id)initWithCoder:(NSCoder *)aDecoder 
     self = [super initWithCoder:aDecoder];
        if (self) 
            self.tableView.delegate = self;
            self.tableView.dataSource = self;
        
        return self;

【讨论】:

【参考方案4】:

如果 dequeueReusableCellWithIdentifier 返回 nil,您只是将单元格出列,但您并没有创建单元格。您应该按照以下方式实施。

static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
if (cell == nil) 
    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];

// here you can configure the cell
return cell

【讨论】:

以上是关于当其父级不是 UITableViewController 时,UITableView 不显示内容的主要内容,如果未能解决你的问题,请参考以下文章

已拒绝访问以解析属性“大小”,因为它不是其父级的“自己的属性”

position: fixed z-index 是不是相对于其父级的 z-index?

Handlebars:访问已被拒绝解析属性“imagePath”,因为它不是其父级的“自己的属性”

Handlebars:访问已被拒绝解析属性“some prop”,因为它不是其父级的“自己的属性”

Handlebars:访问已被拒绝解析属性“_id”,因为它不是其父级的“自己的属性”

解决了! Handlebars:访问已被拒绝解析属性“名称”,因为它不是其父级的“自己的属性”已修复