ios - 以流畅的动画展开 UITableViewCell

标签 ios uitableview uiviewanimation

我正在尝试在 UITableViewCell 的高度发生变化时为它的过渡设置动画。为此,我使用以下代码行:

    [meetingsTable beginUpdates];
    [meetingsTable reloadRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:changedRow inSection:0]] withRowAnimation:UITableViewRowAnimationNone];
    [meetingsTable endUpdates];

但它没有显示行高变化动画。它只显示展开的单元格。但是,如果我删除行

[meetingsTable reloadRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:changedRow inSection:0]] withRowAnimation:UITableViewRowAnimationNone];

它显示了预期的动画高度变化,但单元格没有重新加载。我已经尝试了所有可用的 UITableViewRowAnimation 选项,但没有成功。我也试过了

[meetingsTable reloadData];

但也没有用。 请提出可能的解决方案。

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
BMeetingsTableCell *cell;
cell = [tableView dequeueReusableCellWithIdentifier:@"MEETINGS"];
if (!cell) {
    cell = [[BMeetingsTableCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"MEETINGS"];
}

[self customizeCell:cell atIndexPath:indexPath forTable:tableView];
return cell;
}

- (void)customizeCell:(BMeetingsTableCell *)cell atIndexPath:(NSIndexPath *)indexPath forTable:(UITableView*)tableView shouldReload:(BOOL)shouldReload{
NSDictionary *event;
if (isSearching) {
    event = [NSDictionary dictionaryWithDictionary:[searchedData objectAtIndex:indexPath.row]];
}else if ([tableView isEqual:_activeMeetingsTable])
    event = [NSDictionary dictionaryWithDictionary:[activeEvents objectAtIndex:indexPath.row]];
else if ([tableView isEqual:_completedMeetingTable])
    event = [NSDictionary dictionaryWithDictionary:[completedEvents objectAtIndex:indexPath.row]];
NSArray *partArr;
UILabel *showTimeLbl = (UILabel *)[cell viewWithTag:9];
UIImageView *showNewMeetingIcon = (UIImageView *)[cell viewWithTag:8];
[showTimeLbl setHidden:YES];
[showNewMeetingIcon setHidden:YES];
cell.delegate = self;
cell.tag = indexPath.row;
NSMutableArray* foundConts = [[NSMutableArray alloc]init];
NSMutableArray *tempPartArr = [[NSMutableArray alloc]init];
for (NSDictionary *dict in [event valueForKey:@"users"]) {
    [tempPartArr addObject:dict];
}
partArr = [NSArray arrayWithArray:tempPartArr];
if ([displayName length]==0) displayName = numberString;
NSDictionary *participant = [[NSDictionary alloc]initWithObjectsAndKeys:inviteStat, @"inviteStatus", displayName, @"displayName", nil];
        [foundConts addObject:participant];
    }
}
if ([allParticipants count]> indexPath.row) {
    [allParticipants replaceObjectAtIndex:indexPath.row withObject:invitedConts];
}else
    [allParticipants addObject:invitedConts];
if ([tableView isEqual:_meetingsTable]  && selectedRow == indexPath.row) {
    cell.participants = [NSArray arrayWithArray:foundConts];
    [cell.contsTable setHidden:NO];
    //        [cell.arrowButton setSelected:YES];
    [cell.userImage setImage:[UIImage imageNamed:@"expandedProfilePic.png"]];
}else{
    [cell.userImage setImage:[UIImage imageNamed:@"ProfileImage.png"]];
    [cell.contsTable setHidden:YES];
    //        [cell.arrowButton setSelected:NO];
}


[cell.tapProfileBtn addTarget:self action:@selector(expandDetails:) forControlEvents:UIControlEventTouchUpInside];
cell.tapProfileBtn.tag = indexPath.row;
[cell.title setText:[event valueForKey:@"subject"]];

NSString* location;
if ([[event valueForKey:@"address"] isKindOfClass:[NSNull class]]) {
    location = @"";
}else
    location = [event valueForKey:@"location"];

long long startDateMilliSec = [[event valueForKey:@"start_time_milliseconds"] longLongValue];
NSDate *capturedStartDate = [NSDate dateWithTimeIntervalSince1970:startDateMilliSec];
//
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc]init];
[dateFormatter setDateStyle:NSDateFormatterFullStyle];
NSDateComponents *comps1 = [[NSCalendar currentCalendar] components:NSYearCalendarUnit|NSHourCalendarUnit|NSMinuteCalendarUnit  fromDate:capturedStartDate];
NSString *theYear = [NSString stringWithFormat:@", %ld", (long)comps1.year];
[dateFormatter setDoesRelativeDateFormatting:YES];
[dateFormatter setLocale:[NSLocale currentLocale]];
NSString *dateString = [dateFormatter stringFromDate:capturedStartDate];
if ([dateString isEqualToString:@"Today"]||[dateString isEqualToString:@"Tomorrow"]) {
}else{
    [dateFormatter setDateFormat:@"dd MMMM yyyy"];
    [dateFormatter setDoesRelativeDateFormatting:NO];
    dateString = [dateFormatter stringFromDate:capturedStartDate];
}
NSString *amPM = (comps1.hour>=12)?@"PM":@"AM";
NSString *hourStr = [NSString stringWithFormat:@"%02d",(comps1.hour%12)];
dateString = [dateString stringByReplacingOccurrencesOfString:theYear withString:@""];
NSString *timeString = [NSString stringWithFormat:@"%@:%02d %@",hourStr, comps1.minute, amPM];
NSString *displayString = [NSString stringWithFormat:@"%@ | %@",dateString, timeString];
[cell.date setText:[NSString stringWithFormat:@"%@ | %@", displayString, location]];
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
    if (indexPath.row == selectedRow) {
        NSDictionary* event = [activeEvents objectAtIndex:indexPath.row];
        NSArray *contacts = [event valueForKey:@"users"];
        int height = ([contacts count]*50)+70;
        return height;
    }
  else return 50
}

- (IBAction)expandDetails:(id)sender{
UIButton *btn = (UIButton*)sender;
selectedRow = btn.tag;
BMeetingsTableCell *changedCell = (BMeetingsTableCell*)[_activeMeetingsTable cellForRowAtIndexPath:[NSIndexPath indexPathForRow:btn.tag inSection:0]];
    [self customizeCell:changedCell atIndexPath:[NSIndexPath indexPathForRow:btn.tag inSection:0] forTable:_meetingsTable];
    [_meetingsTable beginUpdates];
    [_meetingsTable endUpdates];
}

最佳答案

您必须在不重新加载表格 View 的情况下更新单元格。

我想您在 cellForRowAtIndexPath 中有您的单元格自定义代码。

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    //dequeue cell
    //customize cell at index path
    return cell;
}

将您的自定义移到它自己的方法中,该方法采用一个单元格。

- (void)customizeCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath {
   //customize cell
}

现在,当您需要更新单元格时,您可以这样做...

- (void)rowWasChanged:(NSInteger)changedRow {
    NSIndexPath *changedIndex = [NSIndexPath indexPathForRow:changedRow inSection:0];
    UITableViewCell *changedCell = [self.meetingsTable cellForRowAtIndexPath:changedIndex];
    [self customizeCell:changedCell atIndexPath:changedIndex];
    [self.meetingsTable beginUpdates];
    [self.meetingsTable endUpdates];
}

关于ios - 以流畅的动画展开 UITableViewCell,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25674460/

相关文章:

iphone - 从列表中搜索

iOS:Autolayout 不适用于动画

ios - 如何在每个 View Controller 中正确管理 NSManagedObjectContext?

ios - registerDefaults 未反射(reflect)在设置应用程序中

iphone - UISlider 的奇怪行为

ios - 从 Storyboard 而不是 nib 加载自定义 TableViewCell

objective-c:执行多个 transitionWithView 动画 block

ios - UIViewAnimationOptionAllowUserInteraction 是否应用于动画 View 或整个屏幕?

ios - PGO:为什么 XCode 会生成空的 .profdata 文件?

ios - AVURLAsset 未加载(.mov 文件)