2011-09-20 10 views
2

사용자 정의 셀이있는 TableView가 있으며 그 중 일부는 이미지가 있고 다른 것은 사용자가 가지고 있지 않습니다. 모든 것은 정상적으로 작동하지만 스크롤을 시작하면 셀이 올바르게 표시되지 않습니다 (이미지가 "잘못된 셀"에 배치되고 가운데를 잘라내 기 때문). 지금이 문제를 해결할 사람이 있습니까?UITableView 스크롤 문제

+1

세포 구성 코드가 표시되어 도움이 될 것입니다. – Jhaliya

+0

코드가 정말 크지 만 주된 목적은 필요에 따라 이미지를 추가하고 그에 따라 셀 높이를 편집하는 것입니다. – superM

+0

테이블에 여러 섹션을 사용하고 있습니까? – Jhaliya

답변

4

중요한 것은 테이블의 셀을 다시 사용한다는 것입니다. 뷰인 새로운 셀을 생성하는 것이 비용이 많이 들기 때문에 스크롤링의 성능을 높이기 위해이 작업이 수행됩니다.

cellForRowAtIndexPath 메서드에서 셀을 반환합니다. 큐 제거 메소드를 사용하는 기존 셀 또는 새 큐를 생성합니다. 그 셀에서, 당신은 당신이 표현하고자하는 것이 무엇이든지의 모든 속성을 설정합니다.

제 생각에는 셀에 이미지 등의 속성을 직접 설정하는 것입니다. 그런 다음 스크롤하면 해당 셀이 다시 사용되고 동일한 이미지가 잘못된 셀에 다시 표시됩니다.

그래서 모델 객체를 유지 관리하는 NSArray와 같은 별도의 인덱스가 필요합니다. 모델 객체는 이미지의 모든 세부 사항을 포함합니다.

예를 들어 봅시다. 나는 10 개의 객체가있는 배열을 가지고 있는데, 처음 5 개는 이미지 "a.png"이고 두 번째 5 개는 "b.png"입니다. I는 cellForRowAtIndexPath의 콜백을 수신하면 다음

, 난 싶지 :

cellForRowAtIndexPath (0,0) 배열 cellForRowAtIndexPath을 a.png되는 인덱스 0을, 객체를 제공 : (0 , 1) a.png 인 배열 1에서 객체를 제공합니다. cellForRowAtIndexPath : (0,2) 배열에서 객체에 인덱스 2 인 a.png를 제공합니다. cellForRowAtIndexPath : (0,3) 배열 a의 객체를 제공합니다. (0,4) a.png 인 배열 4의 인덱스 4에서 객체를 제공합니다. cellForRowAtIndexPath : (0,5) 배열의 인덱스 5에서 객체를 제공합니다. (0,5) a.png 인 cellForRowAtIndexPath : which is b.png cellForRowAtIndexPath : (0,6) 배열에서 인덱스 6 인 b.png 인 객체를 제공합니다. cellForRowAtIndexPath : (0,7) 배열에서 인덱스 7 인 객체를 제공합니다. b.png cellForRowAtIndexPath : 이제

을 b.png하는 인덱스 (9),의가 있다고 생각해 보자 배열에서 객체를 제공한다 (0,9) (0,8)는 배열에서 cellForRowAtIndexPath을 b.png하는 인덱스 (8), 객체를 제공 UITableView에서는 덮개 아래에 다섯 개의 셀이 재사용되고 있습니다. 각 통화

상기 다음 상황이 발생

cellForRowAtIndexPath : (0.1) 어레이에서 인 인덱스 1 객체를 제공한다.png - 기존 셀을 큐에서 삭제하려고 시도하지만 새 셀을 만들 때 "nil"이 다시 나타납니다. 모델 개체의 세부 정보를 설정합니다.

cellForRowAtIndexPath : (0,2) 배열의 인덱스 2 (a.png )의 객체를 제공합니다. 기존 셀을 대기열에서 제외하려고 시도하지만 새 셀을 만들려면 "nil"으로 돌아갑니다. 모델 개체의 세부 정보를 설정합니다.

cellForRowAtIndexPath : (0,3) a.png 인 배열 3의 색인에서 객체를 제공합니다. 기존 셀을 대기열에서 제외하려고 시도하지만 새 셀을 만들려면 "nil"으로 되돌려 야합니다. 모델 개체의 세부 정보를 설정합니다.

cellForRowAtIndexPath : (0,4) 배열의 인덱스 4 (a.png )의 객체를 제공합니다. 기존 셀을 대기열에서 제외하려고 시도하지만 새 셀을 만들려면 "nil"으로 되돌려 야합니다. 모델 개체의 세부 정보를 설정합니다.

cellForRowAtIndexPath : (0,5) 배열에서 인덱스 5 인 b.png 인 개체를 제공합니다. 기존 셀을 큐에서 삭제하려고 시도합니다. 모델 객체의 세부 정보를 설정하여 해당 셀을 다시 사용할 수 있습니다.

cellForRowAtIndexPath : (0,6) 배열에서 인덱스 6 인 b.png 인 객체를 제공합니다. 기존 셀을 큐에서 제거하려고 시도하면 공장! 모델 객체의 세부 정보를 설정하여 해당 셀을 다시 사용할 수 있습니다.

cellForRowAtIndexPath : (0,7) 배열에서 인덱스 7 인 b.png 인 개체를 제공합니다. 기존 셀을 큐에서 제거하려고 시도하면 공장! 모델 개체의 세부 정보를 설정하여 해당 셀을 다시 사용할 수 있습니다.

cellForRowAtIndexPath : (0,8) 배열에서 인덱스 8 인 b.png 인 개체를 제공합니다. 기존 셀을 큐에서 빼내려고하면 공장! 모델 객체의 세부 정보를 설정하여 해당 셀을 다시 사용할 수 있습니다.

cellForRowAtIndexPath : (0,9) 배열에서 인덱스 9 인 b.png 인 개체를 제공합니다. 기존 셀을 큐에서 제거하려고 시도하면 공장! 모델 개체의 세부 정보를 설정하여 해당 셀을 다시 사용할 수 있습니다.

너무 상세해서 죄송합니다! 이게 도움이 되길 바란다. 훌륭한 테이블 뷰 튜토리얼을 통해 작업 해 볼 가치가있을 것입니다. 거기에 많은 사람들이 분명히있을 것입니다.

+0

대단히 감사합니다, 정말 도움이. – superM

+0

우수 사례 .. – Jhaliya

+0

oops 실수로 배열 색인을 만들었습니다. 위의 편집에서 해결되었습니다. 죄송합니다! –

0

테이블 뷰에서 셀 뷰를 요청할 때가 아니라 셀 인스턴스를 만들 때 이미지를 추가하는 것이 좋습니다. 예 :

올바른 방법입니다. 테이블 뷰에서 셀을 요청할 때마다 이미지를 설정합니다.

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"ident"]; 
    UIImageView *imageView; 
    if (cell == nil) { 
     cell = [UITableViewCell alloc] init ....]; 
     imageView = [[UIIMageView alloc] init]; 
     imageView.tag = 123; 
     [cell addSubview:imageView]; 
     [imageView release]; 
    } else { 
     imageView = [cell viewWithTag:123]; 
    } 

    imageView.image = ...; // load image here 
} 

잘못된 방법입니다. 우리는 셀을 만들 때 이미지를 설정합니다. 이렇게하면 셀을 다시 사용할 때 잘못된 이미지가 생깁니다.

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"ident"]; 
    if (cell == nil) { 
     cell = [UITableViewCell alloc] init ....]; 
     UIImageView *imageView = [[UIIMageView alloc] init]; 
     imageView.image = ...; 
     [cell addSubview:imageView]; 
     [imageView release]; 
    } 

} 
+0

그래서, 맞으면 다음 셀이 이전 셀의 "basis"에 구성되어 있습니까? – superM

+0

일종. 표보기는 하나의 화면에 맞추기 위해 필요한만큼의 셀보기 만 작성합니다. 그런 다음 아래로 스크롤하면 사라진 최상위 셀이'dequeueReusableCellWithIdentifier'를 통해 다시 사용되고 하단에 추가됩니다. 이 때문에 셀보기를 만들 때뿐만 아니라 cellForRowAtIndexPath가 호출 될 때마다 셀을 구성해야합니다. –

+0

덕분에 당신의 도움을 많이 – superM

2

세포의 식별자 값을 변경하십시오.

NSString* identifierStr = [NSString stringWithFormat:@"ident_%d",indexPath.row]; 
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifierStr];