我有自定义单元格,在选中时执行短动画,并且在取消选择时应该动画回到它们的第一个状态。
这是我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,所以我有点不知所措。
编辑:添加了完整的方法代码
答案 0 :(得分: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;
}