[ios] 선택하면 UITableViewCell의 높이 변경에 애니메이션을 적용 할 수 있습니까?

UITableViewiPhone 앱에서를 사용하고 있으며 그룹에 속한 사람들의 목록이 있습니다. 사용자가 특정 사람을 클릭하면 (따라서 셀 선택) 셀의 높이가 커져 해당 사람의 속성을 편집하기위한 여러 UI 컨트롤이 표시되도록하고 싶습니다.

이것이 가능한가?



답변

나는 내가 작업하고있는 부작용으로 이것에 대한 정말 간단한 해결책을 찾았 UITableView습니다 …..

을 통해 원래 높이를 정상적으로보고하는 변수에 셀 높이를 저장 한 tableView: heightForRowAtIndexPath:다음 높이 변경에 애니메이션을 적용하려면 변수 값을 변경하고 이것을 호출하십시오.

[tableView beginUpdates];
[tableView endUpdates];

전체 재로드를 수행하지는 않지만 UITableView셀을 다시 그려서 셀의 새 높이 값을 가져와야한다는 것을 알기에 충분합니다 . 그것은 당신을 위해 변화를 애니메이션합니다. 단.

내 블로그에 더 자세한 설명과 전체 코드 샘플이 있습니다 … Animate UITableView 셀 높이 변경


답변

나는 Simon Lee의 답변을 좋아합니다. 실제로 해당 방법을 시도하지는 않았지만 목록의 모든 셀 크기가 변경되는 것처럼 보입니다. 나는 도청 된 세포의 변화를 바라고있었습니다. 나는 약간 시몬처럼 그것을 약간 차이가 있었어요. 셀 선택시 셀 모양이 변경됩니다. 그리고 그것은 움직입니다. 또 다른 방법입니다.

현재 선택된 셀 인덱스의 값을 보유 할 int를 작성하십시오.

int currentSelection;

그때:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    int row = [indexPath row];
    selectedNumber = row;
    [tableView beginUpdates];
    [tableView endUpdates];
}

그때:

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {

    if ([indexPath row] == currentSelection) {
        return  80;
    }
    else return 40;


}

tableView : cellForRowAtIndexPath :에서 유사한 유형을 변경하여 셀 유형을 변경하거나 셀의 xib 파일을로드 할 수 있다고 확신합니다.

이와 같이 currentSelection은 0에서 시작합니다. 목록의 첫 번째 셀 (인덱스 0)이 기본적으로 선택되어 표시되지 않게하려면 조정해야합니다.


답변

선택한 셀을 추적하는 속성 추가

@property (nonatomic) int currentSelection;

(예를 들어)에서 센티넬 값으로 설정 viewDidLoad하여 UITableView시작이 ‘정상’위치에서 시작 되도록하십시오.

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view.

    //sentinel
    self.currentSelection = -1;
}

에서 heightForRowAtIndexPath당신이 높이를 설정할 수 있습니다 당신이 선택한 셀에 대해 원하는

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
    int rowHeight;
    if ([indexPath row] == self.currentSelection) {
        rowHeight = self.newCellHeight;
    } else rowHeight = 57.0f;
    return rowHeight;
}

에서 didSelectRowAtIndexPath당신의 현재 선택 사항을 저장하고 동적 높이 저장, 경우 필요

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
        // do things with your cell here

        // set selection
        self.currentSelection = indexPath.row;
        // save height for full text label
        self.newCellHeight = cell.titleLbl.frame.size.height + cell.descriptionLbl.frame.size.height + 10;

        // animate
        [tableView beginUpdates];
        [tableView endUpdates];
    }
}

에서는 didDeselectRowAtIndexPath센티널 값 선택 인덱스를 다시 설정하고 정상 형태로 되돌아 셀 애니메이션

- (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath {
        // do things with your cell here

        // sentinel
        self.currentSelection = -1;

        // animate
        [tableView beginUpdates];
        [tableView endUpdates];
    }
}


답변

애니메이션이 없기 때문에 reloadData가 좋지 않습니다 …

이것이 현재 시도중인 것입니다.

NSArray* paths = [NSArray arrayWithObject:[NSIndexPath indexPathForRow:0 inSection:0]];
[self.tableView beginUpdates];
[self.tableView insertRowsAtIndexPaths:paths withRowAnimation:UITableViewRowAnimationFade];
[self.tableView deleteRowsAtIndexPaths:paths withRowAnimation:UITableViewRowAnimationFade];
[self.tableView endUpdates];

거의 제대로 작동합니다. 거의. 셀 높이를 높이고 있으며 테이블 뷰의 일부 스크롤 위치가 유지되는 것처럼 셀이 교체 될 때 테이블 뷰에 약간의 “딸꾹질”이 있습니다. 새로운 셀 (첫 번째 셀) 표)의 오프셋이 너무 높으면 스크롤 뷰가 튀어 위치를 변경합니다.


답변

beginUpdates / endUpdates를 연속적으로 호출하는 데 필요한 모든 내용이 무엇인지 모르겠습니다 -[UITableView reloadRowsAtIndexPaths:withAnimation:]. 다음은 예제 프로젝트 입니다.


답변

나는로 해결했다 reloadRowsAtIndexPaths.

didSelectRowAtIndexPath선택한 셀의 indexPath에 저장 reloadRowsAtIndexPaths하고 마지막에 호출 합니다 (다시로드 할 요소 목록에 NSMutableArray를 보낼 수 있음).

에서 heightForRowAtIndexPathindexPath가 목록에 있는지 여부를 expandIndexPath 셀과 보내기 높이가 아닌지 확인할 수 있습니다.

이 기본 예제를 확인할 수 있습니다 :
https://github.com/ferminhg/iOS-Examples/tree/master/iOS-UITableView-Cell-Height-Change/celdascambiadetam
간단한 해결책입니다.

도움이된다면 일종의 코드를 추가하십시오.

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return 20;
}

-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath: (NSIndexPath*)indexPath
{
    if ([indexPath isEqual:_expandIndexPath])
        return 80;

    return 40;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *CellIdentifier = @"Celda";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    [cell.textLabel setText:@"wopwop"];

    return cell;
}

#pragma mark -
#pragma mark Tableview Delegate Methods

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    NSMutableArray *modifiedRows = [NSMutableArray array];
    // Deselect cell
    [tableView deselectRowAtIndexPath:indexPath animated:TRUE];
    _expandIndexPath = indexPath;
    [modifiedRows addObject:indexPath];

    // This will animate updating the row sizes
    [tableView reloadRowsAtIndexPaths:modifiedRows withRowAnimation:UITableViewRowAnimationAutomatic];
}


답변

beginUpdates()/ 대신 endUpdates()권장 통화는 다음과 같습니다.

tableView.performBatchUpdates(nil, completion: nil)

애플은 beginUpdates / endUpdates에 대해 : “가능한 경우이 방법 대신 performBatchUpdates (_ : completion 🙂 메소드를 사용하십시오.”

참조 : https://developer.apple.com/documentation/uikit/uitableview/1614908-beginupdates