Objective C - 仅从超级视图中删除 UIButtons
Objective C - Remove only UIButtons from superview
我是 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 时,复选框再次出现。我尝试从 superview 中删除按钮,但这没有用……有什么建议吗?当我第三次重新加载我的 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];
}
(目前还不完全清楚你在这里想要什么效果,所以我假设你想要一个充满复选框的列,这些复选框根据你的数据模型被选中或未被选中)
您遇到的问题是 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 用户指南中找到实现此目的的具体说明:
您要查找的示例名为 "Creating custom cells",是 "How-tos" 中的最后一个,位于页面底部。
此示例附带一个完整的工作示例,在您下载的 dmg 的示例文件夹中提供。与示例的不同之处在于它使用数据源助手。您的代码不是,但是将数据源助手的 populateCell
方法转换为您习惯使用的 prepareCell
方法相当简单。
我是 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 时,复选框再次出现。我尝试从 superview 中删除按钮,但这没有用……有什么建议吗?当我第三次重新加载我的 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];
}
(目前还不完全清楚你在这里想要什么效果,所以我假设你想要一个充满复选框的列,这些复选框根据你的数据模型被选中或未被选中)
您遇到的问题是 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 用户指南中找到实现此目的的具体说明:
您要查找的示例名为 "Creating custom cells",是 "How-tos" 中的最后一个,位于页面底部。
此示例附带一个完整的工作示例,在您下载的 dmg 的示例文件夹中提供。与示例的不同之处在于它使用数据源助手。您的代码不是,但是将数据源助手的 populateCell
方法转换为您习惯使用的 prepareCell
方法相当简单。