2012-02-14 7 views
8

섹션이있는 tableView를 열고 닫을 수 있습니다. 따라서 섹션을 탭하여 열면 셀로 채워지고 은 -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section에 제공된 것만큼 정확하게 호출됩니다.tableView : cellForRowAtIndexPath : 보이는 셀만 호출하지 않습니까?

맞습니까? 눈에 보이는 세포의 숫자만으로되어서는 안됩니까?

제 경우에는 상황이 좋지 않습니다 : 사용자 정의 셀 (50 ~ 100 셀)을 많이 가지고 있으며 각 셀에 대해 -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)을 호출하면 섹션을 열면 느리게 실행되므로 펜촉에서 읽는 동안 셀 콘텐츠가 이미지로 채워집니다.

if ([[self.tableView indexPathsForVisibleRows] containsObject:indexPath]) 
    NSLog(@"visible %@", indexPath); 

을 그것을 셀 (45)의 밖으로부터 만 6 또는 7이 표시되는지 보여준다 I 이렇게 -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *) 내부 셀의 가시성을 체크했다. 다른 사람들은 눈에 보이는 영역 밖에 있습니다. 그러나 세포를 만드는 것은 여전히 ​​수행되었습니다. 코드는 다음과 같습니다.

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 
static NSString *CellIdentifier = @"IVCell"; 
IVCamera *camera = [server.cameras objectAtIndex:indexPath.row]; 

IVServerListViewCell *cell = (IVServerListViewCell*)[tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 
if (cell == nil) { 
    [[NSBundle mainBundle] loadNibNamed:@"IVServerListCell" owner:self options:nil]; 
    cell = (IVServerListViewCell*)_tableViewCell; 
    self.tableViewCell = nil; 

} 

[cell textLabel].text = camera.cameraName; 
cell.preview = camera.preview; 
cell.userData = camera; 
cell.isEnabled = (server.isInactive)?NO:camera.isOnline; 

return cell; 
} 

여전히 맞습니까? 또는 나는 무엇인가 놓치고 있냐?

답변

5

글쎄, 어떻게 든 내 문제를 다뤘다. 여기에 내 생각과 생각은 어떻게 해결 되었는가? 어쩌면 누군가에게 도움이 될 수 있습니다.

저는 섹션 이벤트를 여는 중에 Instruments를 사용하여 메모리 할당과 호출 스택을 지시했습니다. 대부분의 시간은 nib 파일에서 셀을로드하는 데 소요됩니다. 내가했던 것을 첫째

, 6 뷰 2 개 이미지 대신, 정의의 tableview 세포 (지금은 단지 2 전망이 라벨에 사용되는 뷰의 수를 최소화 nib 파일, 즉의 크기를 줄일 수 있었고 2 레이블 전에). 그것은 나에게 약간의 세포 로딩을 향상시켰다. Apple 설명서에서는 가능한 한 적은 수의 뷰를 사용하고 투명도는 사용하지 말 것을 제안합니다. 따라서 이러한 제안에주의하십시오.

둘째로 이전에 발견 한 것처럼 모든 셀이 -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)으로 생성 된 것은 아니며 nib 파일에서 새로운 셀의로드 수를 줄이기로 결정했습니다. 이를 위해 간단한 아이디어를 보았습니다. 보이지 않는 행에 대해 빈 기본 셀을 반환하고 표시되는 셀에 대해 사용자 지정 셀을로드합니다.

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    if ([self index:indexPath isInvisibleInTableView:tableView]) 
     return [self getBlankCellForTableView:tableView]; 

    // the rest of the method is the same 
    ... 
} 

-(BOOL)index:(NSIndexPath*)indexPath isInvisibleInTableView:(UITableView*)tableView 
{ 
    NSMutableArray *visibleIndexPaths = [self getExtendedVisibleIndexPathsForTableView:tableView]; 

    return ![visibleIndexPaths containsObject:indexPath]; 
} 

-(UITableViewCell*)getBlankCellForTableView:(UITableView*)tableView 
{ 
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"IVBlankCell"]; 
    if (!cell) 
     cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"IVBlankCell"] autorelease]; 

    return cell; 
} 

당신이 볼 수 있듯이, 나는 눈에 보이는 세포를 감지있는 tableview의 단지 -(NSArray*)indexPathsForVisibleRows 방법을 사용하지 않는 : 여기에 코드의 조각이다. 대신, 나는 내 자신의 방법을 작성했습니다 -(NSMutableArray*)getExtendedVisibleIndexPathsForTableView:(UITableView*)tableView. 어떤 이유로 인해 -(NSArray*)indexPathsForVisibleRows을 사용할 때 마지막 하나의 보이는 셀 옆에있는 셀이나 첫 번째 보이는 셀의 이전 셀은 빈 셀로 만들어졌고 스크롤하는 동안 빈 셀처럼 보였기 때문에 필요했습니다. -(NSMutableArray*)getExtendedVisibleIndexPathsForTableView: (UITableView*)tableView에 난 볼 어레이 셀 경계 셀을 추가하고있어,이를 극복하려면

-(NSMutableArray*)getExtendedVisibleIndexPathsForTableView:(UITableView*)tableView{ 
    NSArray *visibleIPs = [tableView indexPathsForVisibleRows]; 

    if (!visibleIPs || ![visibleIPs count]) 
     return [NSMutableArray array]; 

    NSIndexPath *firstVisibleIP = [visibleIPs objectAtIndex:0]; 
    NSIndexPath *lastVisibleIP = [visibleIPs objectAtIndex:[visibleIPs count]-1]; 

    NSIndexPath *prevIndex = ([firstVisibleIP row])?[NSIndexPath indexPathForRow:[firstVisibleIP row]-1 inSection:[firstVisibleIP section]]:nil; 
    NSIndexPath *nextIndex = [NSIndexPath indexPathForRow:[lastVisibleIP row]+1 inSection:[lastVisibleIP section]]; 

    NSMutableArray *exVisibleIndexPaths = [NSMutableArray arrayWithArray:[tableView indexPathsForVisibleRows]]; 

    if (prevIndex) 
     [exVisibleIndexPaths addObject:prevIndex]; 
    [exVisibleIndexPaths addObject:nextIndex]; 

    return exVisibleIndexPaths; 
} 

을 따라서, I는 인스트루먼트 추적에 의해 확인되었다 맞춤 세포 다수 절편을 개방하는 시간을 단축 한 앱을 경험하면서 느꼈다.

+0

나도 이런 문제가 있었고, 당신의 기술은 너무 유용해서 문제가 해결되었습니다. – Ananth

+0

@Ananth 오신 것을 환영합니다! =) – peetonn

0

올바른 것 같습니다. 로딩 자체를 최적화하는 아이디어는 "dequeueReusableCellWithIdentifier"가 작동하는 방식에 있습니다. u가 원격 위치에서 이미지를로드하는 경우이 위치에서 코드를 최적화하고 싶습니다. 하지만 여기에 올바른 보이는 세포의 로딩에서 아닙니다.

+0

슬픈 소리가납니다. 일시적으로 이미지가있는 셀을 채우지 않았으며, 단지 9 개의 셀이있는 섹션과 비교하여 42 개의 셀이있는 섹션을 여는 데는 여전히 약간의 성가신 지연이 있습니다. 여기에있는 유일한 방법은 - 사용자 지정 셀의 펜촉 크기를 줄이고 그 안에 사용 된 uiviews 수를 줄이는 것입니다. 당신은 어떻게 생각하십니까? – peetonn

+0

UITableView에서 섹션을 확장/축소하는 방법이 궁금합니다. 그것은 기본적으로 존재하지 않기 때문입니다. –

+0

'insertRowsAtIndexPaths : withRowAnimation :'과'deleteRowsAtIndexPaths : withRowAnimation :' – peetonn

0

비슷한 기술을 사용했지만 indexPathsForVisibleRows가 정렬되었으므로 containsObject를 사용할 필요가 없습니다. 대신 다음과 같이 할 수 있습니다.

// 
// Checks if indexPath is visible in current scroll state, we are expanding bounds by 1 
// because the cells that are next to the last one visible or the cells that are previous 
// to the first one visible could look empty while scrolling. 
// 
- (BOOL)isIndexPathVisible:(NSIndexPath *)indexPath 
{ 
    NSInteger row = [indexPath row]; 
    NSArray *visible = [self.tableView indexPathsForVisibleRows]; 
    NSInteger count = [visible count]; 
    NSInteger first = (count > 0) ? MAX([visible[0] row] - 1, 0): 0; 
    NSInteger last = (count > 1) ? [visible[1] row] + 1: first + 2; 

    return row >= first && row <= last; 
} 

그건 그렇고, 이 섹션에서는 하나의 섹션 만 사용한다고 가정합니다. 하나 이상의 섹션에서 작동하지 않습니다.

0

다른 문제를 해결하면 내 문제가 해결됩니다. 어디에서 셀을 변경했는지 다시 설정했습니다.

if (! self.cell) { 
    self.cell = [[LanguageCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier]; 
    self.cell.accessoryType = UITableViewCellAccessoryNone; 
} 
else 
{ 
    self.cell.checkImage.image = NO; 

} 
2

테이블 뷰 크기를 확인하십시오. 은 테이블 뷰의 높이가 커서 셀이 모든 테이블 뷰 크기를 채울 때까지 계속로드 될 수 있습니다.

+2

모든 셀의 높이가> 320pt임을 알았을 때 tableView의 estimatedRowHeight를 100pts의 낮은 값으로 설정했습니다. 이것은 100 + 100 + ...> tableView 가시 범위까지 여분의 셀을 불필요하게로드하는 원인이되었습니다. 그런 다음 estimatedRowHeight를 320으로 변경하고로드 된 행 수가 줄어 들었습니다. – SayeedHussain

관련 문제