didSelectRowAtIndexPath一次选择多个行 [英] didSelectRowAtIndexPath selecting more than one row at a time

查看:124
本文介绍了didSelectRowAtIndexPath一次选择多个行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 UITableView 填充27行。我试图更改所选单元格的 accessoryType 。我在 didSelectRowAtIndexPath:委托方法中这样做。



我面临的问题是,并更改单元格的 accessoryType ,该行的第十一行也会被修改。



我已经尝试打印 [indexPath row] 值,但它只显示所选行另一个。



我真的很困惑这样的东西;请帮助我。



添加代码 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 = @全选;
cell.textLabel.font = [UIFont boldSystemFontOfSize:13.0f];
}
else {
cell.textLabel.text = @Some Text Here
cell.detailTextLabel.text = @这里的另一篇文章
}
return cell;

我正在做%10 在第11行后重复,因此尝试为每第11行创建新对象。



我的 didSelectRowAtIndexPath methos代码

  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;
}
}
}

解决方案



/ div>

这里有一种方法:

   - (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;
}

//配置单元格。
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 ;
}

记住表视图中的每个单元格实际上是重复使用的相同对象。如果你没有在每次调用cellForRowAtIndexPath时设置附件类型,当新单元格滚动到屏幕上时,它们都会有相同的附件。



多重选择



多重选择有点复杂。



第一个选项:未记录的API



请注意,这仅在表格处于编辑模式时有效。将每个单元格的编辑样式设置为未记录的UITableViewCellEditingStyleMultiSelect。一旦你这样做,你可以通过UITableView的一个未记录的成员:indexPathsForSelectedRows获得表视图的选择。这应该返回一个选定单元格的数组。



您可以通过将此功能放在标题中来揭示这一点:

 枚举{
UITableViewCellEditingStyleMultiSelect = 3,
};

@interface UITableView(undocumented)
- (NSArray *)indexPathsForSelectedRows;
@end

然后为每个单元格设置编辑样式,如下所示:

   - (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath {
return UITableViewCellEditingStyleMultiSelect;
}

当表处于编辑模式时,您将看到多选控件



要查看其他未记录的API,您可以使用nm命令行实用程序:

  nm /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS4.3.sdk/System/Library/Frameworks/UIKit.framework/UIKit 



第二个选项:自己管理选择



让你的UITableView子类包含一个数组,指示选择哪些单元格。然后在cellForRowAtIndexPath中,使用该数组配置单元格的外观。你的didSelectRowAtIndexPath方法应该看起来像这样:

   - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath * )indexPath 
{
if([tableView indexPathIsSelected:indexPath]){
[tableView removeIndexPathFromSelection:indexPath];
} else {
[tableView addIndexPathToSelection:indexPath];
}
//在这里更新单元格的外观
[tableView deselectRowAtIndexPath:indexPath animated:NO];
}


$ b $ p

这假设您在UITableView子类中创建indexPathIsSelected,removeIndexPathFromSelection和addIndexPathToSelection方法。这些方法应该完全符合其名称的含义:添加,删除和检查数组中的索引路径。如果您使用此选项,则不需要didDeselectRowAtIndexPath实现。


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.

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.

I am really puzzled by such stuff; please help me out.

ADDED THE CODE cellForRowAtIndexPath method

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.

My didSelectRowAtIndexPath methos code is

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!!

解决方案

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.

Multiple Select

For multiple selection it's a bit more complicated.

Your first option: Undocumented 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.

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:

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:

- (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.

这篇关于didSelectRowAtIndexPath一次选择多个行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆