0

我对objective-c还很陌生,遇到了一个我很难解决的问题..

我正在使用 ShinobiDataGrid 并使用他们的 prepareCellForDisplay。

要显示文本,我会这样做:

if([cell.coordinate.column.title isEqualToString:@"Task"]){
            textCell.textField.textAlignment = NSTextAlignmentLeft;
            textCell.textField.text = cellDataObj.task;
        }

但是对于特定的单元格,我正在尝试添加一个自定义按钮:

if([cell.coordinate.column.title isEqualToString:@"selected"]){


            UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
            button.frame = CGRectMake(0, 10 , 32, 32);



            if(cellDataObj.selected){

                [button setImage:[UIImage imageNamed:@"checked-box.png"] forState:UIControlStateNormal];

            }else{

                [button setImage:[UIImage imageNamed:@"unchecked-box.png"] forState:UIControlStateNormal];

            }

            button.tag = cell.coordinate.row.rowIndex;
            [button addTarget:self action:@selector(CheckBoxPressed:) forControlEvents:UIControlEventTouchUpInside];

            [cell addSubview:button];

            [button removeFromSuperview];

        }

我首先运行应用程序,出现复选框。但是当我重新加载我的 ShinobiDataGrid 时,复选框再次出现。我尝试从超级视图中删除该按钮,但这没有用......有什么建议吗?当我第三次重新加载我的 ShinobiDataGrid 时,该复选框第三次没有出现,只是在我第二次重新加载 ShinobiDataGrid 时添加了另一个。这是整个方法:

- (void)shinobiDataGrid:(ShinobiDataGrid *)grid prepareCellForDisplay:(SDataGridCell *)cell
{

    SDataGridTextCell* textCell = (SDataGridTextCell*)cell;

    CellData *cellDataObj = [cellHolderDisplay objectAtIndex:cell.coordinate.row.rowIndex];

    textCell.textField.textAlignment = NSTextAlignmentCenter;

    if([cell.coordinate.column.title isEqualToString:@"selected"]){


        UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
        button.frame = CGRectMake(0, 10 , 32, 32);



        if(cellDataObj.selected){

            [button setImage:[UIImage imageNamed:@"checked-box.png"] forState:UIControlStateNormal];

        }else{

            [button setImage:[UIImage imageNamed:@"unchecked-box.png"] forState:UIControlStateNormal];

        }

        button.tag = cell.coordinate.row.rowIndex;
        [button addTarget:self action:@selector(CheckBoxPressed:) forControlEvents:UIControlEventTouchUpInside];

        [cell addSubview:button];

        [button removeFromSuperview];

    }


    if([cell.coordinate.column.title isEqualToString:@"Task"]){
        textCell.textField.textAlignment = NSTextAlignmentLeft;
        textCell.textField.text = cellDataObj.task;
    }

    if([cell.coordinate.column.title isEqualToString:@"BLine. Start"]){
        textCell.textField.text = cellDataObj.baselineDate;
    }
}

有什么建议么 ?

这是 CheckBoxPressed 方法:

- (void)CheckBoxPressed:(UIButton *)sender
{
    CellData *cell = [cellHolder objectAtIndex:sender.tag];

    if([cell selected] == YES)
    {
        [[cell actualDate]setString:@""];
        [[cell finishedDate] setString:@""];
        [cell setSelected:NO];
    }
    else
    {
        if(([[cell actualDate] isEqualToString:@""]) && ([[cell finishedDate] isEqualToString:@""]))
        {
            [[cell actualDate]setString:[NSString stringWithFormat:@"%@ 8:00:00 AM",[self SetSpecialDateFormat:[NSDate date]]]];
            [[cell finishedDate]setString:[NSString stringWithFormat:@"%@ 4:00:00 PM",[self SetSpecialDateFormat:[NSDate date]]]];
        }
        //actual date not populated but finish date populated
        else if(([[cell actualDate]isEqualToString:@""]) && !([[cell finishedDate] isEqualToString:@""]))
        {
            [[cell actualDate]setString:[cell finishedDate]];
        }
        //finish date not populated but actual date populated
        else if(!([[cell actualDate] isEqualToString:@""]) && ([[cell finishedDate] isEqualToString:@""]))
        {
            [[cell finishedDate]setString:[cell actualDate]];
        }

        [cell setSelected:YES];

    }
    [self UpdateEdittedCells:cell];
    [self SetDisplayHolder];

    //refresh grid
    [gridReference reload];
}
4

1 回答 1

1

(尚不完全清楚您在这里追求什么效果,所以我假设您希望有一列充满复选框,根据您的数据模型选中或取消选中)

您遇到的问题是 shinobi 数据网格重用单元格,以优化内存使用。因此,将按钮添加到单元格意味着按钮将在单元格被重用时出现(当重新加载或滚动网格时)。

可以删除开头的单元格的内容prepareCellForDisplay:,然后您将有一个空单元格,您可以在其中添加按钮:

- (void)shinobiDataGrid:(ShinobiDataGrid *)grid prepareCellForDisplay:(SDataGridCell *)cell
{
  if([cell.coordinate.column.title isEqualToString:@"selected"]){
    NSArray *cellSubviews = [cell.subviews copy];
    for (UIView *subview in subviews) {
      [subview removeFromSuperview];
    }
    // Now safe to add the button
  }
}

然而,这不是最好的方法。

您最好为该selected列创建一个自定义单元格子类。这个单元总是有一个按钮,因此可以更好地利用单元重用机制。

为此,请创建一个 的子类SDataGridCell,并以与通常相同的方式将其注册到网格中。然后,当您收到回调时prepareCellForDisplay:,您知道该类型将是您的自定义类型。

您可以在 ShinobiDataGrid 用户指南中找到实现此目的的具体说明:

https://www.shinobicontrols.com/docs/ShinobiControls/ShinobiGrids/2.8.0/Standard/Normal/docs/markdown_files/DataGridUserGuide.html#How to:创建自定义单元格

您要查找的示例称为“创建自定义单元格”,是“操作方法”的最后一个,位于页面底部。

此示例附带一个完整的工作示例,在您下载的 dmg 中的示例文件夹中提供。该示例的不同之处在于它使用了数据源助手。您的代码不是,但是populateCell将数据源助手的prepareCell方法转换为您习惯使用的方法相当简单。

于 2015-04-26T04:09:33.490 回答