0

選択すると短いアニメーションを実行し、選択を解除すると最初の状態に戻るカスタム セルがあります。

これが私ですsetSelected

- (void)setSelected:(BOOL)selected animated:(BOOL)animated {

if (selected && animated) {
    NSLog(@"animate");
    [UIView animateWithDuration:0.3
                          delay:0.0
                        options:UIViewAnimationOptionBeginFromCurrentState
                     animations:^{
                         self.chevronImage.transform = CGAffineTransformMakeRotation(M_PI);
                         [self.chevronImage setCenter:CGPointMake(self.chevronImage.center.x, self.chevronImage.center.y - 1)];
                     }
                     completion:nil];
}

if (!selected && animated) {
    NSLog(@"unanimate");
    [UIView animateWithDuration:0.3
                          delay:0.0
                        options:UIViewAnimationOptionBeginFromCurrentState
                     animations:^{
                         self.chevronImage.transform = CGAffineTransformMakeRotation(0);
                         [self.chevronImage setCenter:CGPointMake(self.chevronImage.center.x, self.chevronImage.center.y + 1)];
                     }
                     completion:nil];
}

[super setSelected:selected animated:animated];
}

そして、これを呼び出すコードは次のとおりです。

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

if (![selectedIndex isEqual:indexPath]) {
    NSLog(@"select %i", indexPath.row);
    [tableView selectRowAtIndexPath:indexPath animated:YES scrollPosition:UITableViewScrollPositionNone];
}
if (selectedIndex != nil) {
    NSLog(@"deselect %i", selectedIndex.row);
    [tableView deselectRowAtIndexPath:selectedIndex animated:YES];
}
if (controlRowIndex != nil && [indexPath isEqual:controlRowIndex]) {
    return;
}

indexPath = [self modelIndexPathforIndexPath:indexPath];
NSIndexPath *indexPathToDelete = controlRowIndex;

if ([indexPath isEqual:selectedIndex]){
    selectedIndex = nil;
    controlRowIndex = nil;
} else {
    selectedIndex = indexPath;
    controlRowIndex = [NSIndexPath indexPathForRow:indexPath.row + 1
                                         inSection:indexPath.section];
}

[self.tableView beginUpdates];
if (indexPathToDelete){
    [self.tableView deleteRowsAtIndexPaths:@[indexPathToDelete]
                          withRowAnimation:UITableViewRowAnimationFade];
}
if (controlRowIndex){
    [self.tableView insertRowsAtIndexPaths:@[controlRowIndex]
                          withRowAnimation:UITableViewRowAnimationFade];
}
[self.tableView endUpdates];
}

行を選択してからもう一度タップして選択を解除すると、これはうまく機能します。ただし、行 0 をタップしてから行 1 をタップすると、両方の行が選択され、行 0 が選択解除されることはありません。

何が違うのかわかりません。毎回まったく同じ値を渡していますが、現在選択されている場合にのみアニメーション化できます。正しい indexPath を送信していることを確認したので、少し途方に暮れています。

編集:完全なメソッドコードを追加

4

1 に答える 1

0

selectedIndexで変数を設定することを期待していましdidSelectRowAtIndexPath:たが、どこに設定しているのかわかりません。したがって、間違ったインデックス パスと比較しているようです。

概念的には、まず選択解除を行います。

BOOL tappedSelectedCell = [selectedIndex isEqual:indexPath];
if (selectedIndex != nil) {
   // deselect selectedIndex
   selectedIndex = nil;
}

if (selectedIndex == nil && !tappedSelectedCell) {
   // select indexPath
   selectedIndex = indexPath;
}

またはより単純ですが、少し長くなります

if (selectedIndex == nil) {
   // select indexPath
   selectedIndex = indexPath;
   return;
}

if ([selectedIndex isEqual:indexPath]) {
   // deselect indexPath
   selectedIndex = nil;
}
else {
    // deselect selectedIndex
    // select indexPath
    selectedIndex = indexPath;
}
于 2013-03-29T21:36:34.293 に答える