我有一个UITableView
,每行包含一个使用UITableViewCellAccessoryCheckmark
的复选框。我无法弄清楚如何使用didSelectRowAtIndexPath
方法取消选中所有复选框。
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *oldCell;
int count = [self.myTableRowNamesArray count];
for (NSUInteger i = 0; i < count; ++i) {
// Uncheck all checkboxes
// OF COURSE THIS DOESN'T WORK
// BECAUSE i IS AN INTEGER AND INDEXPATH IS A POINTER
FOO: oldCell = [myTableView cellForRowAtIndexPath:(int)i];
// GOOD CODE:
oldCell = [penanceOptionsTableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:i inSection:0]];
oldCell.accessoryType = UITableViewCellAccessoryNone;
}
UITableViewCell *newCell = [myTableView cellForRowAtIndexPath:indexPath];
newCell.accessoryType = UITableViewCellAccessoryCheckmark;
}
答案 0 :(得分:20)
我建议将选定的索引存储在某些ivar中,而不是修改.accessoryType
中所有单元格的didSelectRowAtIndexPath:
,并更改数据中的.accessoryType
来源的-tableView:cellForRowAtIndexPath:
方法,即
-(void)tableView:(UITableView*)tableView didSelectRowAtIndexPath:(NSIndexPath*)indexPath {
self.selectedIndexPath = indexPath;
[tableView reloadData];
}
-(UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath {
...
cell.accessoryType = [indexPath compare:self.selectedIndexPath] == NSOrderedSame
? UITableViewCellAccessoryCheckmark
: UITableViewCellAccessoryNone;
...
}
这样,只会影响可见细胞,并且不需要修改屏幕外的其他数百万个细胞。
非常正确,在选择单元格的一般情况下,这是Swift中的完整实现..您可以根据需要在类中的其他位置使用selectedIndexPath。例如,在cellForRowAtIndexPath
中选择适当的单元格原型。
// SelectingTableViewController
import UIKit
class SelectingTableViewController: UITableViewController
{
internal var selectedIndexPath:NSIndexPath? = nil
override func viewDidLoad()
{
super.viewDidLoad()
tableView.estimatedRowHeight = 68.0
tableView.rowHeight = UITableViewAutomaticDimension
self.clearsSelectionOnViewWillAppear = false;
}
override func tableView
(tableView:UITableView, didSelectRowAtIndexPath indexPath:NSIndexPath)
{
print("did select....")
// in fact, was this very row selected,
// and the user is clicking to deselect it...
// if you don't want "click a selected row to deselect"
// then on't include this clause.
if selectedIndexPath == indexPath
{
print("(user clicked on selected to deselect)")
selectedIndexPath = nil
tableView.reloadRowsAtIndexPaths(
[indexPath],
withRowAnimation:UITableViewRowAnimation.None)
tableView.deselectRowAtIndexPath(indexPath, animated:false)
return
}
// in fact, was some other row selected??
// user is changing to this row? if so, also deselect that row
if selectedIndexPath != nil
{
let pleaseRedrawMe = selectedIndexPath!
// (note that it will be drawn un-selected
// since we're chaging the 'selectedIndexPath' global)
selectedIndexPath = indexPath
tableView.reloadRowsAtIndexPaths(
[pleaseRedrawMe, indexPath],
withRowAnimation:UITableViewRowAnimation.None)
return;
}
// no previous selection.
// simply select that new one the user just touched.
// note that you can not use Apple's willDeselectRowAtIndexPath
// functions ... because they are freaky
selectedIndexPath = indexPath
tableView.reloadRowsAtIndexPaths(
[indexPath],
withRowAnimation:UITableViewRowAnimation.None)
}
}
答案 1 :(得分:11)
for (UITableViewCell *cell in [myTableView visibleCells]) {
cell.accessoryType = UITableViewCellAccessoryNone;
}
但实际上,你最好只修改一个实际上有复选标记设置的单元格。无论如何,您必须将此信息存储在模型中的某个位置。
答案 2 :(得分:5)
您可能正在使用此方法设置某种属性。 所以我做的是:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// 1. first unsetting the property
[object someProperty:nil];
// 2. call the reloadData method to uncheck all the checkmarks
[tableView reloadData];
// 3. check the selected cell
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
[cell setAccessoryType:UITableViewCellAccessoryCheckmark];
// 4. set the checked property
[object setSomeProperty:[indexpath row]];
}
在我的cellForRowAtIndexPath方法中,我得到了类似下面的代码:
if([object someProperty] == [indexpath row]){
[cell setAccessoryType:UITableViewCellAccessoryCheckmark];
} else {
[cell setAccessoryType:UITableViewCellAccessoryNone];
}
答案 3 :(得分:4)
是的,cellForRowAtIndexPath:
使用NSIndexPath
而不是整数,因此请使用
indexPathForRow:inSection:
如果你正在使用一个部分,那么你的循环很好,只需要传入i in row,0传递给section。