Label verschwinden aus TableView

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • Label verschwinden aus TableView

    Ich kapiere es nicht ... X(


    Ich habe eine Tabelle, die mehrere Spalten und Zeilen darstellen kann.
    Der Ordnung halber sei gesagt, dass links noch ein Auswahlhäkchen erscheint und rechts optional noch ein UIButton stehen kann.


    Meine Testdaten liefern für die ersten beiden Tabellenzellen je 3 Werte (2 Label für die obere Zeile, 1 Label für die 2. Zeile), der Rest hat nur 2 Label für die erste Zeile.

    Die Erstellung läuft super, ich kann scrollen und alles sieht klasse aus.


    Das Problem tritt auf, wenn ich
    1. Das Gerät auf die Seite drehe
    2. so weite nach oben scrolle, dass die ersten beiden Zellen weg sind
    3. dann wieder auf Portraitmodus gehe

    denn dann sind die Label der 2. Zeile weg.

    Die UITableViewCell wird recycelt und ich suche dann alle Label aus der Zelle mit [cell.contentView viewWithTag:tag];.
    Nach ewigem Suchen habe ich dann endlich festgestellt, dass nach dem Drehen halt manchmal diese Label nicht mehr da sind.

    Ich habe jetzt den Workaraound, dass in diesen Fällen die Label neu erzeugt werden, aber richtig gefallen kann mir das nicht.
    Nicht nur, dass ich bei langen Listen Speicherprobleme befürchte, ich kapiere auch nicht, warum die Label weg sind.

    Kann es damit zusammen hängen, dass die anderen (dann sichtbaren Zellen) nur 2 Label darstellen?
    Damit es nicht zu falscher Darstellung kommt, setze ich zunächst beim Füllen der Label alle Label der Zelle auf hidden und setze diesen Status nur zurück, wenn ich einen darzustellenden Wert finde.

    Das sieht im NSLog auch alles prima aus, bis ich dann wie beschrieben, das iPhone drehe.

    Kann mir das einer erklären?

    Hier noch ein bisschen Code zum besseren Verständnis:

    Quellcode

    1. -(UILabel *)createLabelAusSpalte:(XmlListSpalte *)spalte maxSpalte:(int) maxSpalte {
    2. float spaltenBreite = [self calcSpaltenBreiteFor:maxSpalte];
    3. int spalteVon, spalteBis;
    4. spalteVon = spalte.iSpalte;
    5. spalteBis = (spalte.iSpan > 1 ? spalteVon + spalte.iSpan - 1 : spalteVon);
    6. float links = spaltenBreite * (spalteVon - 1);
    7. float breite = spaltenBreite * (spalteBis - spalteVon + 1);
    8. if (spalteVon == 1) {
    9. links = links + POS_LINKS;
    10. breite = breite - POS_LINKS;
    11. };
    12. if (spalteBis == maxSpalte) {
    13. breite = breite - POS_LINKS;
    14. }
    15. CGRect rect = CGRectMake(links, spalte.yPos, breite, spalte.fontSize + 4);
    16. UILabel *label = [[[UILabel alloc] initWithFrame:rect] autorelease];
    17. label.tag = [self calcTagForZeile:spalte.iZeile andSpalte:spalte.iSpalte];
    18. [label setNumberOfLines:1];
    19. [label setAdjustsFontSizeToFitWidth:YES];
    20. DLog(@"Neues Label an X=%0.f Y=%0.f W=%0.f H=%0.f Inhalt:%@", label.frame.origin.x, label.frame.origin.y, label.frame.size.width, label.frame.size.height, spalte.sText);
    21. return label;
    22. }
    23. -(void)createObjectsForCell:(UITableViewCell *)cell fromSpalten:(NSArray *)listSpalten inRow:(int)row maxSpalte:(int)maxSpalte {
    24. for (XmlListSpalte *spalte in listSpalten) {
    25. if (spalte.hasBild) {
    26. } else {
    27. UILabel *label = [self createLabelAusSpalte:spalte maxSpalte:maxSpalte];
    28. [cell.contentView addSubview:label];
    29. }
    30. }
    31. }
    32. -(void)fillObjectsForCell:(UITableViewCell *)cell fromSpalten:(NSArray *)listSpalten maxSpalte:(int) maxSpalte {
    33. for (UIView * view in [cell.contentView subviews]) {
    34. if ( [view isKindOfClass:[UILabel class]] ) {
    35. view.hidden = YES;
    36. }
    37. }
    38. for (XmlListSpalte *spalte in listSpalten) {
    39. if (spalte.hasBild) {
    40. } else {
    41. int tag = [self calcTagForZeile:spalte.iZeile andSpalte:spalte.iSpalte];
    42. UILabel *label = (UILabel *)[cell.contentView viewWithTag:tag];
    43. if (!label) {
    44. label = [self createLabelAusSpalte:spalte maxSpalte:maxSpalte];
    45. [cell.contentView addSubview:label];
    46. }
    47. if (label) {
    48. label.text = spalte.sText;
    49. label.opaque = NO;
    50. label.hidden = NO;
    51. TextAttribute *myAttr = [[[BIS_Common sharedInstance] lastXmlData] getTextAttributForListSpalte:spalte];
    52. [TextAttribute attributWithAttribute:listAttribut];
    53. [myAttr mergeTextAttribut:spalte.textAttribut];
    54. [myAttr formatUILabel:label];
    55. //DLog(@"Filled Label an X=%0.f Y=%0.f W=%0.f H=%0.f Inhalt:%@", label.frame.origin.x, label.frame.origin.y, label.frame.size.width, label.frame.size.height, spalte.sText);
    56. }
    57. }
    58. }
    59. }
    60. // Customize the appearance of table view cells.
    61. - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    62. int BTN_INFO_SIZE = 20;
    63. static NSString *EditCellIdentifier = @"listCell";
    64. XmlData *myXmlData = [[BIS_Common sharedInstance] lastXmlData];
    65. XmlListZeile * lZeile = [myXmlData getXmlListZeile:[indexPath row]];
    66. int maxSpalte = myXmlData.xmlListe.maxSpalte;
    67. NSArray *listObjects = [myXmlData getListItemsForRow:[indexPath row]];
    68. if ([indexPath row] == 1) {
    69. for (XmlListSpalte *spalte in listObjects) {
    70. DLog(@"Listobjekt Zeile %d, Spalte %d, Tag %d = %@", spalte.iZeile, spalte.iSpalte, [self calcTagForZeile:spalte.iZeile andSpalte:spalte.iSpalte], spalte.sText);
    71. }
    72. }
    73. UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:EditCellIdentifier];
    74. if (cell == nil) {
    75. //cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:EditCellIdentifier] autorelease];
    76. cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:EditCellIdentifier] autorelease];
    77. //DLog(@"Cell created at X=%0.f Y=%0.f W=%0.f H=%0.f", cell.frame.origin.x, cell.frame.origin.y, cell.frame.size.width, cell.frame.size.height);
    78. [self createObjectsForCell:cell fromSpalten:listObjects inRow:[indexPath row] maxSpalte:maxSpalte];
    79. //DLog(@"Cell labeled at X=%0.f Y=%0.f W=%0.f H=%0.f", cell.frame.origin.x, cell.frame.origin.y, cell.frame.size.width, cell.frame.size.height);
    80. [listAttribut formatUIView:cell];
    81. UIImageView *imageView = [[UIImageView alloc] initWithImage:unselectedImage];
    82. imageView.frame = CGRectMake(0.0, 10.0, 23.0, 23.0);
    83. [listAttribut formatUIView:imageView];
    84. [cell.contentView addSubview:imageView];
    85. imageView.hidden = FALSE;
    86. imageView.tag = kCellImageViewTag;
    87. [imageView release];
    88. if (zeigeDetailButton) {
    89. UIButton *newButton = [UIButton buttonWithType:UIButtonTypeInfoLight];
    90. newButton.frame = CGRectMake(DISPLAY_BREITE - BTN_INFO_SIZE - 1, 7, BTN_INFO_SIZE, BTN_INFO_SIZE);
    91. newButton.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter;
    92. newButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentCenter;
    93. [newButton setTag:kCellInfoButtonTag];
    94. newButton.autoresizesSubviews = YES;
    95. [newButton setAutoresizingMask:UIViewAutoresizingFlexibleLeftMargin];
    96. [newButton addTarget:self action:@selector(clickedListButton:) forControlEvents:UIControlEventTouchUpInside];
    97. [listAttribut formatUIView:newButton];
    98. [cell.contentView addSubview:newButton];
    99. }
    100. }
    101. [self fillObjectsForCell:cell fromSpalten:listObjects maxSpalte:maxSpalte];
    102. if (zeigeDetailButton) {
    103. UIButton *infoButton = (UIButton *)[cell.contentView viewWithTag:kCellInfoButtonTag];
    104. if ([indexPath row] > 0) {
    105. [infoButton setTitle:[NSString stringWithFormat:@"%d", [indexPath row]] forState:UIControlStateApplication];
    106. infoButton.hidden = NO;
    107. } else {
    108. infoButton.hidden = YES;
    109. }
    110. }
    111. UIImageView *imageView = (UIImageView *)[cell.contentView viewWithTag:kCellImageViewTag];
    112. imageView.image = ([lZeile bChecked]) ? selectedImage : unselectedImage;
    113. imageView.hidden = ![lZeile bChecked];
    114. return cell;
    115. }
    Alles anzeigen


    Warum der Code jetzt so bescheiden formatiert ist, weiß ich auch nicht. Er steht zwischen den Code-Tags und bei der Vorschau sah er noch gut aus.
    Ich glaube, ich sollte für heute Feierabend machen ?(
  • Ohne mir das jetzt alles durchzulesen.

    Wenn du zwei verschieden designte Tabellen benutzt, dann must du diesen unterschiedliche Cell Identifier geben. Durch diese unterschiedlichen Identifizier ist sichergestellt, dass nicht eine Zelle reused wird die nicht zur benötigten Cell passt. Sprich wenn eine Zelle x angefordert wird auch nur eine Zelle x gefunden wird und nicht eine Zelle y die gar nicht passt.

    Gruß

    Claus
    2 Stunden Try & Error erspart 10 Minuten Handbuchlesen.

    Pre-Kaffee-Posts sind mit Vorsicht zu geniessen :)
  • Eigentlich gibt es nur ein Design: 2 Label in der ersten und 1 Label in der 2. Zeile.
    Allerdings ist das letzte Label häufig leer und wird daher nicht neu gefüllt.

    So sind in jeder neu erzeugten Zelle 3 Label enthalten. Nach ein wenig scrollen aber fehlt das letzte (und nur das letzte).
    "Optimiert" da jemand ungenutzte Ressourcen automatisch weg?