3

私はUITableView2つのセクションを持っています。ユーザーの操作 (選択と選択解除) に基づいてUITableView、セクション間でデータを移動するためにデータソースと更新が行われます。最初はセクション 0 のデータのみです。セルをタップするwillSelectCellAtIndexPathdidSelectCellAtIndexPath呼び出されます。予想通り、同じセルをもう一度タップすると、 didDeselectCellAtIndexPath呼び出されます。

データをセクション 1 に移動し、選択と選択解除を開始した後でも、UITableView'sデリゲート メソッドが適切に呼び出されます。

すべてのデータがセクション 1 に移動されると、UITableViewは奇妙な動作を示し始めます。最初にコールを選択でき、コールさdidSelectCellAtIndexPathれます。ただし、もう一度タップすると、didDeselectCellAtIndexPath呼び出されません。代わりに、選択したセルをタップすると (実際に選択されている[tableView indexPathsForSelectedCells]か、セクション 1 の他のセルのみが呼び出される ことwillSelectIndexPathを確認しました。didSelectIndexPath

これらのデリゲート メソッドには、関連のないかなりの量のコードがあります (私は信じています)。セルの選択状態を明示的に変更することはありません。willSelectメソッドを投稿しました。必要に応じてさらに投稿できます。

- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath{
if (remainingItemIsSelected && indexPath.section == 0) {
        //other cells in the remaining items section are selected and a cell from that section is being selected

        NSMutableIndexSet *arrayIndexesToBeDeleted = [[NSMutableIndexSet alloc] init];
        for (NSIndexPath *previouslySelectedIndexPath in [tableView indexPathsForSelectedRows]) {
            if (((ReceiptItem *)[self.remainingReceiptItems objectAtIndex:previouslySelectedIndexPath.row]).allocated == YES) {

                //update data sources
                NSLog(@"%@%i%@,%i",@"Section #:",previouslySelectedIndexPath.section,@" Row #:",previouslySelectedIndexPath.row);
                [self.assignedReceiptItems addObject:[self.remainingReceiptItems objectAtIndex:previouslySelectedIndexPath.row]];
                [arrayIndexesToBeDeleted addIndex:previouslySelectedIndexPath.row];

                //update index path arrays
                [self.receiptItemsToDeleteIndexPaths addObject:previouslySelectedIndexPath];
                [self.receiptItemsToAddIndexPaths addObject:[NSIndexPath indexPathForRow:self.assignedReceiptItems.count-1 inSection:1]];

                //update the pressed indexpath to equal to resulting indexpath to pass on to the didSelect method
                if (previouslySelectedIndexPath.row < indexPath.row) {
                    indexPath = [NSIndexPath indexPathForRow:indexPath.row-1 inSection:0];
                }
            }
        }
        //Delete assigned items from the remaining receipt items
        [self.remainingReceiptItems removeObjectsAtIndexes:arrayIndexesToBeDeleted];
        //update table (move allocated item down)
        [tableView beginUpdates];
        [tableView deleteRowsAtIndexPaths:self.receiptItemsToDeleteIndexPaths withRowAnimation:UITableViewRowAnimationAutomatic];
        [tableView insertRowsAtIndexPaths:self.receiptItemsToAddIndexPaths withRowAnimation:UITableViewRowAnimationAutomatic];
        [tableView endUpdates];
        if (self.remainingReceiptItems.count == 0) {
            [tableView reloadSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:UITableViewRowAnimationAutomatic];
        }
        //other cells in the remaining items section are selected and a cell from assigned items is being selected
        return nil;
    }
    return indexPath;
}
4

1 に答える 1

1

UITableViewDelegateのドキュメントから:

tableView:willDeselectRowAtIndexPath:
このメソッドは、ユーザーが別の行を選択しようとしたときに既存の選択がある場合にのみ呼び出されます。デリゲートには、前に選択した行に対してこのメ​​ソッドが送信されます。

これをよく考えてみると、これは予期された動作であることがわかります。選択されている行をタップしても、この行は呼び出されませwill/didDeselctRowAtIndexPath

代わりにdidSelectRowAtIndexPath、選択した行に対してこれを処理できます。つまり、そこで選択を解除できます。

可能な代替

UITableViewそうは言っても、あなたはクラスを悪用していると思います。実際には、この感動的なことを行うようには設計されていません。あなたは間違いなく、これを機能させるために多くのコードを書かなければならないことに気づいたでしょう。まさにそれが、手に負えないエラーに遭遇している理由です。

datasourceよりクリーンな (そして最終的にはより柔軟な) 解決策は、変更についてデリゲートを介して互いに通知する 2 つの別個のテーブル (またはその他の) ビューを持つことです。セットアップにはもう少し手間がかかるかもしれませんが、今後のトラブルは確実に少なくなります。

于 2013-03-13T23:05:44.643 に答える