如何在一个UITableView中维护具有不同布局的单元格

时间:2013-10-11 09:07:42

标签: ios objective-c cocoa-touch uitableview

任何人都可以帮助我理解我的UITableView我做错了吗?

我设置了一个包含两个自定义单元格的消息列表 - 取决于变量是true还是false。我想将我的数据应用到相关的单元格 - 但我得到的是两个自定义单元格在下面重复3次,如下所示(前景中的单元格没有样式 - 仅举例来说!)< / p>

enter image description here

这是我的代码 -

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath     *)indexPath
{
    static NSString *CellIdentifier = @"Cell";
    static NSString *CellIdentifierRead = @"CellRead";

    CustomCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier  forIndexPath:indexPath];

    customCellRead *cellRead = [tableView dequeueReusableCellWithIdentifier:CellIdentifierRead forIndexPath:indexPath];

    notifications *n = [self.GPTNotifications objectAtIndex:indexPath.row];

    if (n.read == false) {
        cellRead.readText.text =n.notifMessage;
        cellRead.reDate.text =n.notifDateD;
        cellRead.resub.text = n.notifDateD;

    }
    if (n.read == true) {


       cell.notifTitle.text = n.notifTitleD;
       cell.notifDate.text = n.notifDateD;
       cell.notifMsg.text = n.notifMessage;
    }

// Configure the cell...

    return cell;
    return cellRead;
}

3 个答案:

答案 0 :(得分:3)

首先,我们必须了解UITableView的工作原理。使用委托模式,它会询问控制器必须在给定索引处显示哪个单元格。

第一种方法是在init或viewDidLoad方法初始化一个UITableViewCell实例数组,并在tableView上提供好的单元格:cellForRowAtIndexPath:

基本上

- (void)viewDidLoad
self.cells = @[myCell1, myCell2];

- (UITableViewCell *)tableView:cellForRowAtIndexPath:index
return self.cells[index.row];

但是你必须记住,列表的设计可能包含大量的单元格。因此Apple设计了一种方法来实现这一目标。操纵实体总是比UI元素更好。因此,Apple为您提供了一种“回收”细胞的方法。在给定时间,屏幕上的单元格少于10个。

因此,当一个单元格离开屏幕时,tableView会将其保留在内存中以供日后使用。当一个单元格进入屏幕时,您可以使用dequeueReusableCellWithIndentifier:@"MyCell"在此回收队列中获取一个单元格。在开始时,队列中找不到任何单元格,因此它将返回nil。所以你必须初始化一个单元格。

static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
//Do initial visual configuration here
cell.textLabel.textColor = [UIColor redColor];
}
// Get entity 
Notification entity = self.GPTNotifications[indexPath.row];
// Configure the according
cell.textLabel.text = entity.x;

return cell;

因此,对于您的确切问题,我们首先要知道的是: 根据读取属性,您是否有2个tableView或2种单元?

对于第二个问题,你的方法应该是这样的:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath     *)indexPath
{
    notifications *n = [self.GPTNotifications objectAtIndex:indexPath.row];
    CustomCell *cell;
    if (n.read)
    {
            static NSString *CellIdentifierRead = @"CellNotifRead";
        cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifierRead];
        if (cell == nil)
            cell = [[CustomCell alloc] init];

        cell.notifTitle.text = n.notifTitleD;
        cell.notifDate.text = n.notifDateD;
        cell.notifMsg.text = n.notifMessage;
    }
    else
    {
            static NSString *CellIdentifier = @"CellNotifUnread";
        cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
        if (cell == nil)
            cell = [[CustomCell alloc] init];

        cellRead.readText.text =n.notifMessage;
        cellRead.reDate.text =n.notifDateD;
        cellRead.resub.text = n.notifDateD;
    }
    return cell;
}

答案 1 :(得分:2)

  1. 您不能使用2个返回语句,只会执行第一个语句;

  2. 如果您的单元格是否为零,则应添加一项检查。如果是,你应该初始化它

  3. 默认方法如下所示:

    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
    }
    
    // Configure the cell...
    
    return cell;
    

答案 2 :(得分:1)

return cell;
return cellRead;

在C语言和所有其他具有return语句的语言中,任何方法都会在到达第一个return语句时保留并终止,return cellRead;将永远不会到达。

而不是为2种不同的布局使用一个自定义单元格,您应该使用2。

- (void) viewDidLoad {
   [super viewDidLoad];

   [self.tableView registerClass:[MyCell class] forCellReuseIdentifier:@"Cell"];
   [self.tableView registerClass:[MyReadCell class] forCellReuseIdentifier:@"CellRead"];
}


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath     *)indexPath
{
    static NSString *CellIdentifier = @"Cell";
    static NSString *CellIdentifierRead = @"CellRead";

    UITableView *cell;


    notifications *n = [self.GPTNotifications objectAtIndex:indexPath.row];

    if (n.read == false) {
        cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
        MyReadCell *cellRead = (MyReadCell *)cell;
        cellRead.readText.text =n.notifMessage;
        cellRead.reDate.text =n.notifDateD;
        cellRead.resub.text = n.notifDateD;

    }
    if (n.read == true) {
        cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifierRead forIndexPath:indexPath];
        MyCell *myCell = (MyCell *)cell;
        myCell.notifTitle.text = n.notifTitleD;
        myCell.notifDate.text = n.notifDateD;
        myCell.notifMsg.text = n.notifMessage;
    }

    // Configure the cell...

    return cell;
}