2009-12-22 4 views
3

UITableViewCoreData을 통해 채워지고 이상한 것으로 나타났습니다. 나는 약 20 줄 정도의 UITable을 가지고 있는데, 테이블을 아래로 스크롤하여 다시 올리면 셀의 레이블이 기존 텍스트의 맨 위에 쓰여지고 내려갈 때마다 계속해서 작업을 수행합니다. CellForRowAtIndexPath에 대한 내 코드는 다음과 같습니다Objective-C : 위아래로 스크롤 할 때마다 UITableView 셀이 쓰여집니다.

// Customize the appearance of table view cells. 
    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 
//Some constants --- 
const NSInteger TOP_LABEL_TAG = 1001; 
const NSInteger BOTTOM_LABEL_TAG = 1002; 
UILabel *topLabel; 
UILabel *bottomLabel; 
const CGFloat LABEL_HEIGHT = 20; 
//CGRect Imageframe = CGRectMake(7, 5, 35, 35); 
//---- 



static NSString *CellIdentifier = @"Cell"; 

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 
if (cell == nil) { 
    cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease]; 
    cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; 
    cell.textLabel.font = [UIFont boldSystemFontOfSize:12]; 
} 

//custom implementation of UIView for lazy loading of image 
//LazyUIImageView *lazy = [[LazyUIImageView alloc] initWithFrame:Imageframe]; 


//[cell addSubview:lazy]; 



Post *post = [fetchedResultsController objectAtIndexPath:indexPath]; 

NSSet *medias = post.PostMedia; 
Media *media = [medias anyObject]; 
NSSet *thumbs = media.MediaThumb; 
Thumb *thumb = [thumbs anyObject]; 


UIImage *img = thumb.url; 

if (img) 
    cell.imageView.image = img; 
else 
    cell.imageView.image = post.authorpic; 

//The creation of the top label 
topLabel = 
[[[UILabel alloc] 
    initWithFrame: 
    CGRectMake(
      35 + 2.0 * cell.indentationWidth, 
      0.5 * (tableView.rowHeight - 2 * LABEL_HEIGHT), 
      tableView.bounds.size.width - 
      45 - 4.0 * cell.indentationWidth 
      - 35, 
      LABEL_HEIGHT)] 
autorelease]; 
[cell.contentView addSubview:topLabel]; 

topLabel.tag = TOP_LABEL_TAG; 
topLabel.backgroundColor = [UIColor clearColor]; 
topLabel.textColor = [UIColor colorWithRed:0.25 green:0.0 blue:0.0 alpha:1.0]; 
topLabel.highlightedTextColor = [UIColor colorWithRed:1.0 green:1.0 blue:0.9 alpha:1.0]; 
topLabel.font = [UIFont systemFontOfSize:[UIFont labelFontSize]]; 
//--------------------------------- 

//The creation of the bottom label 
bottomLabel = 
[[[UILabel alloc] 
    initWithFrame: 
    CGRectMake(
      35 + 2.0 * cell.indentationWidth, 
      0.5 * (tableView.rowHeight - 2 * LABEL_HEIGHT) + LABEL_HEIGHT, 
      tableView.bounds.size.width - 
      35 - 4.0 * cell.indentationWidth 
      - 35, 
      LABEL_HEIGHT)] 
autorelease]; 
[cell.contentView addSubview:bottomLabel]; 
//-------------------------------- 

// 
// Configure the properties for the text that are the same on every row 
// 
bottomLabel.tag = BOTTOM_LABEL_TAG; 
bottomLabel.backgroundColor = [UIColor clearColor]; 
bottomLabel.textColor = [UIColor colorWithRed:0.25 green:0.0 blue:0.0 alpha:1.0]; 
bottomLabel.highlightedTextColor = [UIColor colorWithRed:1.0 green:1.0 blue:0.9 alpha:1.0]; 
bottomLabel.font = [UIFont systemFontOfSize:[UIFont labelFontSize] - 2]; 

// 
// Create a background image view. 
// 
cell.backgroundView = 
[[[UIImageView alloc] init] autorelease]; 
cell.selectedBackgroundView = 
[[[UIImageView alloc] init] autorelease];; 


topLabel.text = post.title; 
bottomLabel.text = @"put something here"; 


// 
// Set the background and selected background images for the text. 
// Since we will round the corners at the top and bottom of sections, we 
// need to conditionally choose the images based on the row index and the 
// number of rows in the section. 
// 
UIImage *rowBackground; 
UIImage *selectionBackground; 
NSInteger sectionRows = [tableView numberOfRowsInSection:[indexPath section]]; 
NSInteger row = [indexPath row]; 
if (row == 0 && row == sectionRows - 1) //all 
{ 
    rowBackground = [UIImage imageNamed:@"topAndBottomRow.png"]; 
    selectionBackground = [UIImage imageNamed:@"topAndBottomRowSelected.png"]; 
} 
else if (row == 0) //top 
{ 
    rowBackground = [UIImage imageNamed:@"topRow.png"]; 
    selectionBackground = [UIImage imageNamed:@"topRowSelected.png"]; 
} 
else if (row == sectionRows - 1) //bottom 
{ 
    rowBackground = [UIImage imageNamed:@"bottomRow.png"]; 
    selectionBackground = [UIImage imageNamed:@"bottomRowSelected.png"]; 
} 
else //middle 
{ 
    rowBackground = [UIImage imageNamed:@"middleRow.png"]; 
    selectionBackground = [UIImage imageNamed:@"middleRowSelected.png"]; 
} 
((UIImageView *)cell.backgroundView).image = rowBackground; 
((UIImageView *)cell.selectedBackgroundView).image = selectionBackground; 


//[lazy release]; 

return cell; 

} 사전에 도움을

감사합니다!

답변

8

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

이 줄은 존재하는 경우 세포의 오프 스크린 기존 재사용하기 위해 응용 프로그램을 말하고있다. 따라서 기본적으로 이미 존재하는 셀을 가져 와서 서브 뷰가 이미 종료 된 동일한 위치에서 새 서브 뷰를 추가합니다. 새 하위 뷰를 추가하기 전에 기존 하위 뷰를 지워야합니다. 귀하의 코멘트에 대답

업데이트 :

1월의 코드는 기존의 파단을 제거합니다. if 셀의 else 절이 nil 문이므로 위 코드에 추가합니다.

if (cell == nil) { 
    cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease]; 
     cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; 
    cell.textLabel.font = [UIFont boldSystemFontOfSize:12]; 
} 
else { 
    UIView* subview; 
    while ((subview = [[[cell contentView] subviews] lastObject]) != nil) 
     [subview removeFromSuperview]; 
} 

: 당신이 사용할 수있는 재사용 가능한 전지 (셀 == 전무)가없는 경우

그래서, 코드가 다른 코드는 기존의 세포에서 이전 파단을 제거, 새로운 하나를 생성합니다 대체는 같은 일을 달성하는 더 간결한 방법은 다음과 같습니다

if (cell == nil) { 
    cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease]; 
    cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; 
    cell.textLabel.font = [UIFont boldSystemFontOfSize:12]; 
} 
else { 
    [[[cell contentView] subviews] makeObjectsPerformSelector: @selector(removeFromSuperview)]; 
} 
+0

고맙지 만, 내가 어디에서 이걸 할까? cell.subviews = nil합니까? 또는 whats 베팅 방법 – Doz

+0

jan의 코드는 기존 서브 뷰를 제거합니다. if 셀의 else 절이 nil 문이므로 위 코드에 추가합니다. 나는 위의/if 논리로 위의 내 대답을 편집했습니다. –

+0

고마워, 너희 둘다 굉장 했어. 그리고 더 중요하게는 셀 == nil 개념을 조금 더 이해할 수있었습니다. – Doz

4

셀이 캐시되고 이미 추가 된 항목을 제거하지 않고 콘텐츠보기에 계속 추가하기 때문입니다.

더 구체적인 셀 식별자를 사용하고 셀을 만들 때 콘텐츠 뷰에 ​​추가하거나 콘텐츠 뷰를 지우고 레이블을 다시 추가 할 수 있습니다.

셀의 파단을 지우려면이를 추가 할 수 있습니다!

if(cell == nil) 
{...} 
else 
{ 
    UIView* subview; 
    while ((subview = [[[cell contentView] subviews] lastObject]) != nil) 
     [subview removeFromSuperview]; 
} 

때 셀 = 당신이 이미 생성 및 하위 뷰에 추가 한 셀을 의미 전무는, 그건 그들이 삭제해야하는 이유 .

+0

레이블을 다시 추가하기 전에 콘텐츠보기를 지우는 것은 무엇을 의미합니까? 이 대리자 메서드의 시작 부분에 내가 어디에 넣을까요? – Doz

1

을 우리가 jQuery과에 대한 재사용 식별자를 사용 이제까지는 전지를 재사용 할 필요가 있음을 이해하고하면 서로 덮어 세포의 값 우리는 셀 식별자의 인덱스 값을 지정하지 않습니다. 재사용 할 수 있습니다.

인덱스 경로에서 셀을 다시 사용하기 위해 테이블보기 셀에 구체적으로 알려야합니다.

NSString *cellIdentifier = [NSString stringWithFormat:@"S%1dR%1d",indexPath.section,indexPath.row]; 

UITableViewCell *cell = (UITableViewCell *)[tableView dequeueReusableCellIdentifier:cellidentifier]; 

이것은 하나 another.More 작성 극복하지 않는 세포에서의 세포 및 값 중 MIS 통신을 제거한다면 (셀 == 전무)이 셀 식별자를 사용하여 이를 통해 인덱스 위치 또는 셀 인덱스 값 간의 통신이 번거롭지 않습니다.희망이 도움, 감사합니다 :)

1

여러 번 스크롤 및 장치의 위치를 ​​변경할 때 응용 프로그램이 중단 될 수 있기 때문에 UITableViewCell 자동 렌더링 싶지 않아요.

0

셀이 nil이 아닌 경우 else 조건의 하위 뷰를 제거 할 수 있습니다.

static NSString *CellIdentifier = @"CellIdentifier";   
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 

    //create a uitableviewcell 
    if(cell == nil) 
    { 
    //Do whatever you want to do 

    }else{ 
     [[cell.contentView viewWithTag:YOUR_TAG] removeFromSuperview]; 
    } 
관련 문제