以编程方式创建UITableView [英] Creating a UITableView Programmatically

查看:61
本文介绍了以编程方式创建UITableView的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在Xcode 4.6中有一个使用情节提要的应用程序.我将UITableView添加到视图控制器类中,该类按预期工作.但是,当我尝试在情节提要中删除UITableView并以编程方式将其重新添加到同一类中时,遇到了两个具体问题:

I have an application in Xcode 4.6 which uses storyboards. I added a UITableView to a view controller class, which worked as expected. However, when I tried deleting the UITableView in the storyboard and adding it back into the same class programmatically, I ran into two specific problems:

1)尽管我将UITableViewCell类型设置为字幕类型,但不再显示详细标签.

2)当我选择一个单元格时不会发生应该进行的segue,甚至没有调用准备segue,这表明在选择一个cell时没有消息发送到表视图.

以下是相关代码:

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

@end

@implementation StatsTableViewController

-(UITableView *)makeTableView
{
    CGFloat x = 0;
    CGFloat y = 50;
    CGFloat width = self.view.frame.size.width;
    CGFloat height = self.view.frame.size.height - 50;
    CGRect tableFrame = CGRectMake(x, y, width, height);

    UITableView *tableView = [[UITableView alloc]initWithFrame:tableFrame style:UITableViewStylePlain];

    tableView.rowHeight = 45;
    tableView.sectionFooterHeight = 22;
    tableView.sectionHeaderHeight = 22;
    tableView.scrollEnabled = YES;
    tableView.showsVerticalScrollIndicator = YES;
    tableView.userInteractionEnabled = YES;
    tableView.bounces = YES;

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

    return tableView;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    self.tableView = [self makeTableView];
    [self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"newFriendCell"];
    [self.view addSubview:self.tableView];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"newFriendCell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];

    if (cell == nil) 
    {
        cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
    }

    Friend *friend = [self.fetchedResultsController objectAtIndexPath:indexPath];

     **//THIS DATA APPEARS**
    cell.textLabel.text = friend.name;
    cell.textLabel.font = [cell.textLabel.font fontWithSize:20];
    cell.imageView.image = [UIImage imageNamed:@"icon57x57"];

    **//THIS DATA DOES NOT APPEAR**
    cell.detailTextLabel.text = [NSString stringWithFormat:@"%i Games", friend.gameCount];
    cell.detailTextLabel.textColor = [UIColor lightGrayColor];

    return cell;
}

 -(void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath
{
    [self performSegueWithIdentifier:@"detailsView" sender:self];
}

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
      //I set the segue identifier in the interface builder
     if ([segue.identifier isEqualToString:@"detailsView"])
     {

         NSLog(@"segue"); //check to see if method is called, it is NOT called upon cell touch

         NSIndexPath *indexPath = [self.tableView indexPathForCell:sender];
         ///more code to prepare next view controller....
     }
}

我不确定要做什么才能解决这两个问题.感谢您的帮助.

I am not sure what I am forgetting to do so that I can solve these two issues. Any help is appreciated.

推荐答案

当您注册一个类并使用dequeueReusableCellWithIdentifier:forIndexPath:时,保证该dequeue方法返回一个单元格,因此您的if(cell == nil)子句永远不会输入.因此,以旧的方式进行操作,不要注册该类,而使用dequeueReusableCellWithIdentifier:

When you register a class, and use dequeueReusableCellWithIdentifier:forIndexPath:, the dequeue method is guaranteed to return a cell, so your if (cell == nil) clause is never entered. So, just do it the old way, don't register the class, and use dequeueReusableCellWithIdentifier:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"newFriendCell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    if (cell == nil) {
        cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
    }
//etc.
return cell;
}

对于segue来说,它不能被调用,因为您不能对通过代码而不是在IB中创建的表进行segue.再次,回到旧方法并使用tableView:didSelectRowAtIndexPath:,当您选择一个单元格时将调用它.在那里实例化细节控制器并执行代码中的转换.

As for the segue, it can't be called because you can't make a segue to a table that you've created in code, not in IB. Again, go back to the old way and use tableView:didSelectRowAtIndexPath: which will be called when you select a cell. Instantiate your detail controller there and do the trasition in code.

编辑后:

我在那里没有看到您添加的代码.您已实现didDeselectRowAtIndexPath而不是didSelectRowAtIndexPath.如果您更改了该设置,则您的segue应该可以正常工作.

I didn't see your added code there. You've implemented didDeselectRowAtIndexPath rather than didSelectRowAtIndexPath. If you change that, your segue should work.

这篇关于以编程方式创建UITableView的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆