0

セットアップ:「Item(NSStringitemName、NSStringitemPrice)」のリストに設定されている「_itemListArray(ivar)」というプロパティがあります。UITableViewにこれらの項目を入力すると、ユーザーは複数の行を選択して、その行にチェックマークを表示できます。チェックされたセルのindexPathはIVAR(_selectedItemRows)に保存されます。ユーザーが行を再度選択すると、チェックマークアクセサリがnoneに設定され、indexPathがIVAR(_selectedItemRows)から削除されます。「cellForRowAtIndexPath」では、現在キューに入れられているindexPathを、_selectedItemRows(チェックされたセルのindexPathの配列)内のすべてのindexPathと照合します。インデックスパスが配列内にある場合は、デキューされたセルをチェックし、そうでない場合は、チェックを外します。

問題:チェックマークアクセサリは正しく設定されていますが(didSelectRowAtIndexPath)、スクロールするとファンキーに動作します。たとえば、最初のセルをチェックしてから下にスクロールしてから上にスクロールすると、nslogsはプログラムがセルをチェックすることを認識していることを確認しましたが、そうではないようです。
また、2つ以上のセルをチェックする場合は、下にスクロールしてから上にスクロールします。通常、チェックされるのは最後のセルだけです。

コード

@implementation  
@synthesize itemListArray = _itemListArray;  
@synthesize selectedItemRows = _selectedItemRows;  
-(void)setItemListArray:(NSArray *)itemListArray  
{  
    _itemListArray = itemListArray;  
    [_propTableView reloadData];  
}  
- (void)viewDidLoad  
{  
    [super viewDidLoad];  
    _selectedItemRows = [[NSMutableArray alloc] init];  
}  
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section  
{  
    // Return the number of rows in the section.  
    return [_itemListArray count];  
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath  
{  
    static NSString *CellIdentifier = @"Item Selected Reuse"; //Identifier of prototype cell  
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];     

    if (nil == cell) { //If somethong goes wrong, all hell breaks loose.  
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];  
         NSLog(@"%s", __PRETTY_FUNCTION__);  
    }  
    // Configure the cell...  
    Item *curItem = [_itemListArray objectAtIndex:indexPath.row]; //Get the model information at row location.  
    cell.textLabel.text = curItem.itemName; //Set the name of the item in title field  
    cell.detailTextLabel.text = curItem.itemPrice; //Set the price of the item in the detail field.  
    for(NSIndexPath * elem in _selectedItemRows)
    { //Enumerate through checked cells  
        //NSIndexPath *ip = [_selectedItemRows objectAtIndex:x];  
        if ([indexPath compare:elem] == NSOrderedSame) { //If the current cell index path ='s any index path in the array of checked cells, check this cell.  
            cell.accessoryType = UITableViewCellAccessoryCheckmark;   
        } else {  
            cell.accessoryType = UITableViewCellAccessoryNone;  
        }  
    }  
    return cell;  
}  
//pragma mark - Table view delegate  
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath  
{  
    UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath]; //Get cell clicked on.   
    if(cell.accessoryType == UITableViewCellAccessoryNone){ //When selected, if the cell is checked, uncheck it.  
        cell.accessoryType = UITableViewCellAccessoryCheckmark;  
        [_selectedItemRows addObject:indexPath]; //Add the index path of checked cell into array to use later for comparisons  
    } else {  
        if(cell.accessoryType == UITableViewCellAccessoryCheckmark){ //If the cell is checked, uncheck it when clicked on  
            cell.accessoryType = UITableViewCellAccessoryNone;  
            [_selectedItemRows removeObject:indexPath]; //Remove that index path of unchecked cell from index array  
        }  
    }  
    [tableView deselectRowAtIndexPath:indexPath animated:YES];//Deselect row after done.  
}  
@end  
//Other code left out for brevity sake  

4

1 に答える 1

1

コードに論理エラーがあります。このコードで何が起こるか考えてみてください。

for(NSIndexPath * elem in _selectedItemRows)
{ //Enumerate through checked cells  
    //NSIndexPath *ip = [_selectedItemRows objectAtIndex:x];  
    if ([indexPath compare:elem] == NSOrderedSame) { //If the current cell index path ='s any index path in the array of checked cells, check this cell.  
        cell.accessoryType = UITableViewCellAccessoryCheckmark;   
    } else {  
        cell.accessoryType = UITableViewCellAccessoryNone;  
    }  
}  

現在の行のインデックスパスがセル内の最後のパスでない限り、_selectedItemRowsチェックマークはオフになります。検出時にチェックマークを設定し、_selectedItemRows検索を続行するときに設定を解除します。代わりに、これを次のようなものに置き換えます。

cell.accessoryType = UITableViewCellAccessoryNone; 
for(NSIndexPath * elem in _selectedItemRows)
{ //Enumerate through checked cells  
    //NSIndexPath *ip = [_selectedItemRows objectAtIndex:x];  
    if ([indexPath compare:elem] == NSOrderedSame) { //If the current cell index path ='s any index path in the array of checked cells, check this cell.  
        cell.accessoryType = UITableViewCellAccessoryCheckmark;
        break;
    }  
}  
于 2012-09-06T01:56:13.470 に答える