2012-11-19 3 views
1

아래 표시된 테이블 뷰에는 label이 포함되어 있습니다. 각 셀에 대해 subView으로 추가됩니다.레이블 텍스트가 섞여 있습니다.

프로그램을 처음 실행하면 화면에 나타나는 셀의 텍스트가 올바르게 표시됩니다. 그러나 테이블을 스크롤하면 레이블의 텍스트가 섞이기 시작합니다. 셀이 만들어지면 한 셀의 레이블이 다른 셀의 레이블 위에 겹쳐 있다는 것을 알 수 있습니다. 이것은 후자의 두 스크린 샷에 나와 있습니다. 각 스크롤 후에 다른 셀이 다른 셀 위에 겹쳐집니다. (그래서 고정 된 패턴이 없습니다.) 나는 스크린 밖으로 나가는 셀과 들어가는 셀을 관찰함으로써이 문제를 이해하려고 노력했습니다. 이 정보를 세포의 레이블과 연관 시키려고했지만 이해할 수는 없습니다.

이 불일치의 원인을 이해하도록 친절하게 도와주세요.

고마워요!

enter image description here

다음 내 코드의 관련 섹션입니다 같이

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    static NSString *CellIdentifier = @"Cell"; 
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 

    if (cell == nil) 
    { 
     cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier]; 
    } 

    cell.selectionStyle = UITableViewCellSelectionStyleNone; 

    NSLog(@"s = %d, r = %d", indexPath.section, indexPath.row); 

    if (indexPath.section == 0) 
    { 
     switch(indexPath.row) 
     { 
      case 0: 
      [cell addSubview:classA]; 
      break; 

      case 1: 
      [cell addSubview:classB]; 
      break; 

     case 2: 
      [cell addSubview:classC]; 
      break; 

     case 3: 
      [cell addSubview:classD]; 
      break; 

     case 4: 
      [cell addSubview:classE]; 
      break; 

     default: 
      break; 
    } 
} 

if(indexPath.section == 1) 
{ 
    switch(indexPath.row) 
    { 
     case 0: 
      [cell addSubview:classF]; 
      break; 

     case 1: 
      [cell addSubview:classG]; 
      break; 

     case 2: 
      [cell addSubview:classH]; 
      break; 

     default: 
      break; 
    } 
} 

if(indexPath.section == 2) 
{ 
    switch (indexPath.row) 
    { 
     case 0: 
      [cell addSubview:classI]; 
      break; 

     case 1: 
      [cell addSubview:classJ]; 
      break; 

     case 2: 
      [cell addSubview:classK]; 
      break; 

     default: 
      break; 
    } 
} 

return cell; 
} 

답변

1

이유는 dequeueReusableCellWithIdentifier을 사용하여 셀을 다시 사용하기 때문입니다. 따라서 스크롤 할 때 보이는 영역을 벗어나는 셀은 현재 보이는 셀에서 재사용되고 있습니다.

classB 등의 레이블을이 셀에 이미 추가 했으므로이 셀에서 제거되지 않고 이후에 제거되지 않으며 이후에 동일한 재사용 된 셀에 classI 등의 레이블을 추가 할 때 그 위에 그려집니다 이 라벨의 이 레이블은 배경색이 선명한 색으로 설정되어 있기 때문에 뒤쪽에 그려진 레이블이 표시되어 중복되는 느낌을줍니다.

스크린 샷에 따르면 모든 셀이 동일하게 보이므로 dequeueReusableCellWithIdentifier으로 셀을 확실히 재사용 할 수 있습니다. 그렇다면 cellForRowAtIndexPath 외부의 레이블을 만드는 논리를 변경하지 말고 대신 cell.TextLabel.text = @"Class B"; 등으로 사용하십시오.이 메서드 내부의 해당 if 조건에서? 귀하의 코드는 모양을

,

if (indexPath.section == 0) 
    { 
     switch(indexPath.row) 
     { 
      case 0: 
      cell.textLabel = [self createLabelForRow:indexPath.row section:indexPath.section]; 
//or if it is jut a simple label, you can just set font and other properties in cell.textLabel directly 
      cell.textLabel.text = @"Class A"; 
      break; 

업데이트 : 여기 모든 세포가 정적 경우 dequeueReusableCellWithIdentifier 재사용을위한 그리 좋은 수정합니다. 하지만이 방법은 권장되지 않습니다.

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 

    NSString *CellIdentifier = [NSString stringWithFormat:@"CellForRow%dSection%d",indexPath.row, indexPath.section]; 
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 
    if (cell == nil) 
    { 
     cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier]; 
   } 

    //or try this 

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:nil]; 
    if (cell == nil) 
  { 
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:nil]; 
    } 

갱신 2 : 위의와 그래서 당신이 직면하는 경우 문제가 이것을 시도. 나의 첫 번째 접근 방식을 사용하고 다음을 수행하십시오.

if (indexPath.section == 0) 
    { 
     switch(indexPath.row) 
     { 
      case 0: 
      cell.textLabel = [self createLabelForRow:indexPath.row section:indexPath.section]; 

      // or do the following, 

      [self removeAllTextFieldsFromCell:cell]; 
      UITextField *aTextField = [self createTextFieldForRow:indexPath.row section:indexPath.section]; 
      [cell.contentView addSubview:aTextField]; 
     } 

removeAllTextFieldsFromCell:에서는 R.A의 제안을 사용합니다.예를 들어

는 : -

단지
- (void)removeAllTextFieldsFromCell:(UITableViewCell *)cell { 

    for (UITextField *textField in cell.contentViews.subViews) { 
     [textField removeFromSuperView]; 
    } 
} 

또는 사용

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    static NSString *CellIdentifier = @"Cell"; 
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 

    if (cell == nil) 
    { 
     cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier]; 
    } 

    cell.selectionStyle = UITableViewCellSelectionStyleNone; 

    NSLog(@"s = %d, r = %d", indexPath.section, indexPath.row); 

    //if it is all textfields in the cell, it will look like, 
    [self removeAllTextFieldsFromCell:cell]; 
    UITextField *aTextField = [self createTextFieldForRow:indexPath.row section:indexPath.section]; 
    [cell.contentView addSubview:aTextField]; 

    return cell; 
} 
+0

. 'cell.textLabel.text'는 확실히 옵션이고 나는 그것을 탐구했다. 그러나'textFields'를 사용하면 유사한 문제가 발생합니다. 그래서 저는이 문제를 해결하기 위해 정말로 열심입니다. –

+0

'dequeueReusableCellWithIdentifier' 대신에 무엇을 할 수 있습니까? –

+0

@Rut, 텍스트 필드에서 직면 한 문제는 무엇입니까? 이 경우 새 레이블을 추가하기 전에 셀에서 이전에 추가 된 모든 하위 뷰를 제거하는 논리가 필요할 수 있습니다. 어쨌든 내 업데이트를 확인하십시오. 그러면 문제가 해결 될 것입니다. – iDev

3

테이블보기 세포가 다시 있습니다 : 당신이 위 또는 아래로 스크롤하면 dequeueReusableCellWithIdentifier가 이전에 사용 된 셀을 반환 할 수 있습니다 다른 (이제 보이지 않는) 행에 대해.

그런 경우 셀에 이미 하위보기 중 하나가 포함되어 있고 하위보기를 추가합니다.

+0

귀하의 회신에 감사드립니다. 세포가 보이지 않는다면 여전히 기억 속에 남아 있습니까? 나는 그것이 삭제 될 것이라고 생각 했는가? 'dequeueReusableCellWithIdentifier'에 대한 대안은 무엇입니까? –

+0

테이블 뷰는 정적 (고정 행/섹션 수) 또는 동적입니까? 얼마나 많은 세포 유형이 있습니까? –

+0

셀은 정적입니다. 고유 한 텍스트가 들어있는 11 개의 셀이 있습니다. –

1

당신은 당신이 당신의 세포에서 remove the oldtextField 필요, textfield으로 코멘트에 말했듯이. if statement for indexPath.section checking 앞에이 코드를 추가 할 수 있습니다.

for (UITextField *textField in cell.contentViews.subViews) { 
    [textField removeFromSuperView]; 
} 
+0

코멘트 주셔서 감사합니다 R.A. 셀을 여러 개 선택했습니다. 첫 번째 화면의 일부 셀을 선택한 것으로 가정하고'removeFromSuperView'를 사용하면 선택한 셀이 다시 나타날 때 선택 항목이 유지됩니까? –

+0

이것은 모든 것을 관리해야하는 곳입니다. iOS에서는 선택 사항을 유지 관리하지 않으므로 사용자가 여러 셀을 선택하면이를 저장해야하며 테이블 뷰를 스크롤 할 때 해당 셀을 다시 선택하십시오. 그렇게하지 않으면 다른 셀을 선택하는 것과 같은 오류가 발생합니다. 그냥 질문에 대답하십시오. –

+0

removeFromSuperView는 셀의 다른 요소에 영향을 미치지 않습니다. 현재 셀에 쓸모없는 textField를 제거해야합니다. 모두 –

관련 문제