ios didSelectRowAtIndexPath 一次选择多于一行
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6057819/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
didSelectRowAtIndexPath selecting more than one row at a time
提问by devsri
I have a UITableView
populated with 27 rows. I am trying to change the accessoryType
of the selected cell. I do that in the didSelectRowAtIndexPath:
delegate method.
我有一个UITableView
填充了 27 行。我正在尝试更改accessoryType
所选单元格的 。我在didSelectRowAtIndexPath:
委托方法中这样做。
The problem I am facing is that, when selecting a row and changing the accessoryType
of the cell, the eleventh row from that row also gets modified.
The problem I am facing is that, when selecting a row and changing the accessoryType
of the cell, the eleventh row from that row also gets modified.
I have tried printing the [indexPath row]
value, but it's showing only the row that was selected and not another one.
我试过打印该[indexPath row]
值,但它只显示被选中的行而不是另一行。
I am really puzzled by such stuff; please help me out.
我真的被这些东西弄糊涂了;请帮帮我。
ADDED THE CODEcellForRowAtIndexPath
method
添加了代码cellForRowAtIndexPath
方法
UITableViewCell *cell;
if ([indexPath row] == 0) {
cell = [tableView dequeueReusableCellWithIdentifier:@"acell"];
}
else {
cell = [tableView dequeueReusableCellWithIdentifier:@"bcell"];
}
cell.selectionStyle = UITableViewCellSelectionStyleNone;
if (cell == nil && [indexPath row] != 0) {
cell = [[[UITableViewCell alloc] initWithStyle:
UITableViewCellStyleSubtitle reuseIdentifier:@"bcell"] autorelease];
}
else if(cell == nil && [indexPath row] == 0){
cell = [[[UITableViewCell alloc] initWithStyle:
UITableViewCellStyleSubtitle reuseIdentifier:@"acell"] autorelease];
}
if ([cell.contentView subviews]){
for (UIView *subview in [cell.contentView subviews]) {
[subview removeFromSuperview];
}
}
if ([indexPath row] == 0) {
cell.textLabel.text = @"Select All";
cell.textLabel.font = [UIFont boldSystemFontOfSize:13.0f];
}
else {
cell.textLabel.text = @"Some Text Here"
cell.detailTextLabel.text = @"Another piece of text here"
}
return cell;
I am doing %10
because the behaviour is repeating after 11th row, hence trying to create new object for every 11th row.
我这样做%10
是因为该行为在第 11 行之后重复,因此尝试为每第 11 行创建一个新对象。
My didSelectRowAtIndexPath
methos code is
我的didSelectRowAtIndexPath
方法代码是
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
if (cell.accessoryType == UITableViewCellAccessoryCheckmark) {
if ([indexPath row] != 0) {
NSIndexPath *tempIndex = [NSIndexPath indexPathForRow:0 inSection:0];
UITableViewCell *tempCell = [tableView cellForRowAtIndexPath:tempIndex];
tempCell.accessoryType = UITableViewCellAccessoryNone;
}
cell.accessoryType = UITableViewCellAccessoryNone;
}
else{
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
if ([indexPath row] == 0) {
for (int i = 0; i < [dataSource count]; i++) {
NSIndexPath *tempIndex = [NSIndexPath indexPathForRow:i+1 inSection:0];
UITableViewCell *tempCell = [tableView cellForRowAtIndexPath:tempIndex];
if (cell.accessoryType == UITableViewCellAccessoryCheckmark) {
tempCell.accessoryType = UITableViewCellAccessoryCheckmark;
}
else{
tempCell.accessoryType = UITableViewCellAccessoryNone;
}
}
}
Please help me in multiple selection or anyother way to solve the problem of multiple selection.
请帮助我进行多选或任何其他方式来解决多选问题。
Thanks in advance!!
提前致谢!!
回答by daxnitro
Here's one way to do it:
这是一种方法:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
[cell.textLabel setText:[NSString stringWithFormat:@"Row %d", indexPath.row]];
NSIndexPath* selection = [tableView indexPathForSelectedRow];
if (selection && selection.row == indexPath.row) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
} else {
cell.accessoryType = UITableViewCellAccessoryNone;
}
// Configure the cell.
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView cellForRowAtIndexPath:indexPath].accessoryType = UITableViewCellAccessoryCheckmark;
}
- (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView cellForRowAtIndexPath:indexPath].accessoryType = UITableViewCellAccessoryNone;
}
Remember every cell in the table view is actually the same object being re-used. If you don't set the accessory type every time cellForRowAtIndexPath is called, when new cells scroll onto the screen they're going to all have the same accessory.
记住表格视图中的每个单元格实际上都是被重用的同一个对象。如果您没有在每次调用 cellForRowAtIndexPath 时设置附件类型,当新单元格滚动到屏幕上时,它们都将具有相同的附件。
Multiple Select
多选
For multiple selection it's a bit more complicated.
对于多项选择,它有点复杂。
Your first option: Undocumented API
您的第一个选择:未记录的 API
Note that this only works when the table's in editing mode. Set each cell's editing style to the undocumented UITableViewCellEditingStyleMultiSelect. Once you do that, you can get the table view's selection via an undocumented member of UITableView: indexPathsForSelectedRows. That should return an array of the selected cells.
请注意,这仅在表格处于编辑模式时有效。将每个单元格的编辑样式设置为未记录的 UITableViewCellEditingStyleMultiSelect。一旦你这样做了,你就可以通过 UITableView 的一个未记录的成员获取表视图的选择:indexPathsForSelectedRows。这应该返回所选单元格的数组。
You can expose this bit of functionality by putting this in a header:
您可以通过将其放在标题中来公开这一功能:
enum {
UITableViewCellEditingStyleMultiSelect = 3,
};
@interface UITableView (undocumented)
- (NSArray *)indexPathsForSelectedRows;
@end
Then set the editing style for each cell like so:
然后为每个单元格设置编辑样式,如下所示:
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath {
return UITableViewCellEditingStyleMultiSelect;
}
When the table is in editing mode you'll see the multi-select controls on your cells.
当表格处于编辑模式时,您将在单元格上看到多选控件。
To look through other undocumented API, you can use the nm command line utility like this:
要查看其他未记录的 API,您可以使用 nm 命令行实用程序,如下所示:
nm /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS4.3.sdk/System/Library/Frameworks/UIKit.framework/UIKit
Your second option: Manage the selection yourself
您的第二个选择:自己管理选择
Have your UITableView subclass contain an array that indicates which cells are selected. Then in cellForRowAtIndexPath, configure the cell's appearance using that array. Your didSelectRowAtIndexPath method should then look something like this:
让您的 UITableView 子类包含一个数组,指示选择了哪些单元格。然后在 cellForRowAtIndexPath 中,使用该数组配置单元格的外观。您的 didSelectRowAtIndexPath 方法应该如下所示:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if ([tableView indexPathIsSelected:indexPath]) {
[tableView removeIndexPathFromSelection:indexPath];
} else {
[tableView addIndexPathToSelection:indexPath];
}
// Update the cell's appearance somewhere here
[tableView deselectRowAtIndexPath:indexPath animated:NO];
}
This assumes you create indexPathIsSelected, removeIndexPathFromSelection, and addIndexPathToSelection methods in your UITableView subclass. These methods should do exactly what their names imply: Add, remove, and check for index paths in an array. You wouldn't need a didDeselectRowAtIndexPath implementation if you go with this option.
这假设您在 UITableView 子类中创建了 indexPathIsSelected、removeIndexPathFromSelection 和 addIndexPathToSelection 方法。这些方法应该完全按照它们的名称来执行:添加、删除和检查数组中的索引路径。如果使用此选项,则不需要 didDeselectRowAtIndexPath 实现。
回答by Hobey Kuhn
Remember every cell in the table view is actually the same object being re-used. If you don't set the accessory type every time cellForRowAtIndexPath is called, when new cells scroll onto the screen they're going to all have the same accessory." - daxnitro
记住表格视图中的每个单元格实际上都是被重用的同一个对象。如果您没有在每次调用 cellForRowAtIndexPath 时设置附件类型,当新单元格滚动到屏幕上时,它们都将具有相同的附件。”- daxnitro
This is where I got caught. I had mine set up so that in my "cellForRowAtIndexPath" function, I would only change the accessory for those specified in my array of checked cells, when what I should have done was update the accessory for all cells in the table.
这是我被抓住的地方。我已经设置好我的“cellForRowAtIndexPath”函数,我只会更改在我检查的单元格数组中指定的附件,而我应该做的是更新表格中所有单元格的附件。
In other words:
换句话说:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
//normal set up
//retrieve key
NSUserDefaults *settings = [NSUserDefaults standardUserDefaults];
id obj = [settings objectForKey:@yourKey];
//if the array is not populated, keep standard format for all cells
if (obj == nil){
selectedStyles = [[NSMutableArray alloc] initWithObjects:nil];
[cell setAccessoryType:UITableViewCellAccessoryNone]; //no check mark
[cell textLabel].textColor = [[UIColor alloc] initWithRed:0.0/255 green:0.0/255 blue:0.0/255 alpha:1.0]; //keep black color
}
//else retrieve information from the array and update the cell's accessory
else{
//if the cell is in your array, add a checkbox
[cell setAccessoryType:UITableViewCellAccessoryCheckmark]; //add check box
[cell textLabel].textColor = [[UIColor alloc] initWithRed:50.0/255 green:79.0/255 blue:133.0/255 alpha:1.0]; //change color of text label
//if the cell is not in your array, then keep standard format
[cell setAccessoryType:UITableViewCellAccessoryNone]; //no check mark
[cell textLabel].textColor = [[UIColor alloc] initWithRed:0.0/255 green:0.0/255 blue:0.0/255 alpha:1.0]; //keep black color
Hope this helps!
希望这可以帮助!