2010-04-13 6 views
0

UITableView에서 스크롤하면 셀이 겹칩니다. 내가 뭘 잘못하고 있니? UITableView에서 스크롤 한 후 항목이 섞여 있습니다.

내 방법 :

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    static NSString *CellIdentifier = @"Cell"; 
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 
    if (cell == nil) { 
     cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease]; 
    } 
    [cell insertSubview:[itemArray objectAtIndex:indexPath.row] atIndex:indexPath.row]; 
    return cell; 
} 

업데이트

그것은 지금 cell.contentView를 사용하여 작동하지만 지금은 항목을 선택하면, 선택한 하나는의 내용 오버레이됩니다 다른 셀 ...

답변

8

TechZen의 조언은 정확합니다. 귀하의 코드에서 insertSubview : atIndex를 오해 하셨음이 분명합니다. 나는 또한 tableView : cellForRowAtIndexPath :가 호출 될 때와 호출되지 않을 때를 더 잘 이해할 필요가 있다고 생각한다.

불행히도 여기에서는 sagar의 나쁜 조언을 듣게되었습니다. 특히, 처음에는 작동하는 것처럼 보일 수 있지만 화면 이동 성능과 메모리 사용량은 줄어 듭니다. 자신의 이익을 위해 tableView : cellForRowAtIndexPath : 및 재사용 식별자 개념을 명확히하려고 노력하겠습니다.

tableView : cellForRowAtIndexPath : 및 재사용 식별자를 이해하는 핵심 요소는 UITableViewCell을 구축하는 것이 비용이 많이 든다는 것을 이해하는 것입니다. 당신이해야 할 모든 것을 고려해

  1. 셀의 파단을 할당 셀
  2. 을 할당합니다.
  3. 셀 내의 하위 뷰 레이아웃을 정의하십시오.
  4. 하위 뷰를 셀에 추가하십시오. 등 폰트 크기, 색상, 텍스트 배치, 크기 조절 동작 등 같은 보조 이미지로 셀
  5. 구성 특성 등 파단의
  6. 구성 속성
  7. 특정 텍스트 및/또는 이미지를 정의 셀을 표시하려고합니다.

테이블을 만들 때 일반적으로 셀의 기본 구성이 동일해야합니다. 그들은 일반적으로 동일한 위치에서 동일한 글꼴을 사용하는 같은 수의 하위 뷰를 갖습니다. 실제로 셀 하나에서 다음 셀로 변해야하는 유일한 것은 위 목록의 항목 7, 텍스트 및 세포에 의해 표시된 이미지.

1 ~ 6 단계는 매우 비쌉니다 (특히 메모리 할당). 따라서 우리가 만든 모든 셀에 대해 이러한 단계를 거치면 스크롤 성능이 저하되고 셀을 스크롤하면 화면. 화면에서 화면을 스크롤 할 때 셀을 저장할 수 있다면 내용을 수정하고 표시해야하는 다음 셀로 다시 사용할 수 있습니다.

애플은이 셀 재사용 최적화의 필요성을 인식하여 UITableView에 바로 구현할 수있는 메커니즘을 만들었습니다. 셀이 화면 밖으로 스크롤하면 UITableView가이를 버리지 않습니다. 대신 셀의 재사용 식별자 문자열을보고 해당 식별자와 연결된 특수 버퍼에 셀을 넣습니다. 다음에 dequeueReusableCellWithIdentifier를 호출하면 동일한 식별자로 UITableView가 해당 버퍼에서 셀을 가져와 재사용 할 수있게합니다. 이 셀에는 이전과 동일한 구성의 서브 뷰가 모두 있으므로 모든 목록에서 7 단계 만 수행하면됩니다. 셀의 텍스트 및/또는 이미지를 업데이트하기 만하면 바로 사용할 수 있습니다.

이 메커니즘을 올바르게 사용하면 표시되는 각 행에 대해 하나의 버퍼와 버퍼에 대해 하나의 셀만 할당하게됩니다. 테이블에 몇 개의 행이 있더라도 메모리 사용량은 낮게 유지되고 스크롤은 버터만큼 부드럽습니다.

Sagar는 각 행마다 다른 재사용 식별자를 사용하도록 권장했습니다. 바라기를 당신은 이것이 왜 나쁜 생각인지 알 수 있습니다. 각 셀이 화면에서 스크롤하면 테이블 뷰는 셀의 식별자를보고 고유하다는 것을 확인하고 해당 특정 행에 대한 새 버퍼를 만듭니다. 10,000 개의 행을 스크롤하면 테이블 뷰는 각각 10,000 개의 버퍼로 끝나며 각 셀은 단일 셀 전용으로 사용됩니다. 10,000 개의 셀 객체를 생성하는 동안 스크롤이 불필요하게 느려지고 테이블 아래쪽에 도달하기 전에 앱의 메모리가 부족한 상태가됩니다.

그럼 일반적인 셀 식별자를 유지하십시오. if (cell == nil) { } 블록 안에 모든 셀에 공통적 인 모든 설정 코드를 입력하십시오. 해당 블록 아래에는 각 행에 고유 한 내용을 채우는 코드 만 넣으십시오. 행마다 내용을 변경하려는 사용자 정의 하위 뷰에 액세스하려면 - [UIView viewWithTag :]를 사용하거나 더 나은 방법으로 UITableViewCell의 하위 클래스를 만들고 사용자 정의 하위 뷰를 하위 클래스의 속성으로 표시 할 수 있습니다.

+0

+1 매우 도움이되는 설명, 감사합니다! –

1

여기에 문제는 셀 자체가 아닌 셀 내부의 뷰 계층 구조에 행 논리를 적용한다는 것입니다.

이 라인 :

[cell insertSubview:[itemArray objectAtIndex:indexPath.row] atIndex:indexPath.row]; 

배열에서 도면을 취하고 셀의 기존 서브 뷰 스택 특정 index.row에서 셀의 파단에 추가한다. 적절한 뷰 자체가 적절한 셀에 삽입되었는지 확인하는 데는 아무런 효과가 없습니다. 이전 반복에서 뷰를 제거하지 않으면 재사용 된 개별 셀 내에서 이러한 모든 뷰가 스택으로 표시됩니다.

적어도 하나를 추가하기 전에 이전에 추가 한 모든 셀 하위보기를 제거해야합니다. 셀의 contentView보기에만 하위보기를 추가하고 셀 자체에는 하위보기를 추가하지 않아야합니다.

그래서 여기

[[cell.contentView.subviews objectAtIndex:0] removeFromSuperview]; 
[cell.contentView addSubview:[itemArray objectAtIndex:indexPath.row]]; 
+0

> cell.contentView addSubview가 트릭을 수행했습니다. – jean

관련 문제