2010-03-22 9 views
22

Ich habe eine gruppierte UITableView, wo nicht alle Abschnitte auf einmal angezeigt werden können, wird die Tabelle von einigen Daten, die nicht jeder Datensatz haben kann angetrieben. Mein Problem ist, dass die Aufzeichnungen, die bestimmte nicht über Abschnitte als Leerzeichen in der Tabelle angezeigt (siehe Bild)Gruppiert UITableView zeigt Leerzeichen, wenn Abschnitt leer ist

alt text http://img220.imageshack.us/img220/5633/screenshot20100322at228.png

Es sind keine Fußzeilen/Header. Alles, was ich verpasst habe?

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 
// Return the number of rows in the section. 
return [self getRowCount:section]; 
} 


// Customize the appearance of table view cells. 
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 

static NSString *CellIdentifier = @"Cell"; 

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

cell.textLabel.text = [NSString stringWithFormat:@"section: %d row: %d",indexPath.section,indexPath.row]; 
// Configure the cell... 

return cell; 
} 

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { 

    float height = 0.0; 

    if([self getRowCount:indexPath.section] != 0){ 
     height = kDefaultRowHeight; 
    } 

    return height; 

} 

Antwort

6

In dem obigen Screenshot ist Ihre numberOfSectionsInTableView: Methode einen Wert von 5 zurückkehrt? Und dann ist Ihre getRowCount: Methode (von numberOfRowsInSection: aufgerufen), die einen Wert von 0 für diese "fehlenden" Abschnitte (z. B. 1, 3 und 4) zurückgibt?

Wenn Sie keine Lücken dazwischen haben möchten, besteht die wahrscheinliche Lösung darin, nur die Anzahl der Abschnitte anzugeben, die sichtbar sein sollen. In Ihrem obigen Beispiel möchten Sie nur den Wert 3 von numberOfSectionsInTableView: zurückgeben.

0

Ich glaube, dass mit Abschnitt Tabellenansichten jeder Abschnitt vorhanden sein muss, und jeder Abschnitt hat Pufferraum für eine Kopf- und Fußzeile unabhängig davon, dass Sie Text in ihnen einfügen. Was Sie tun müssen, ist, die Abschnitte zu entfernen, die nicht verwendet werden. In Ihrem Beispiel würden Sie Abschnitt 1, 3, entfernen und 4. Dies würde bedeuten:

"Abschnitt 0" ist indexPath.section == 0

"Abschnitt 2" indexPath.section == 1

„Abschnitt 5“ ist indexPath.section == 2

Wenn Sie Code in dieser Art und Weise werden die Kopf- und Fußzeilen entfernt werden, da die Null-Zelle entfernt wird.

Das ist natürlich keine richtige Kodierung, aber ich wollte Ihnen nur eine Vorstellung von der Theologie geben. Hoffe, das hilft.

38

Ich habe eine ähnliche Situation und mein Datenmodell funktioniert wirklich besser, wenn ich es leere Abschnitte haben lassen kann.

Ihr Problem kann gelöst werden, wenn Sie in Ihrem Tableview-Controller self.tableView.sectionHeaderHeight = 0; und self.tableView.sectionFooterHeight = 0; setzen. Diese müssen 0 sein, weil die Delegatmethoden irgendwie einen Rückgabewert von 0. ignorieren Dann müssen Sie einige Delegatmethoden außer Kraft setzen:

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section { 
    if (section==0) 
     return sectionGapHeight; 
    if ([self tableView:tableView numberOfRowsInSection:section]==0) { 
     return 0; 
    } 
    return sectionGapHeight; 
} 
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section { 
    if (section==[self numberOfSectionsInTableView:tableView]-1) { 
     return sectionGapHeight; 
    } 
    return 0; 
} 
- (UIView *)sectionFiller { 
    static UILabel *emptyLabel = nil; 
    if (!emptyLabel) { 
     emptyLabel = [[UILabel alloc] initWithFrame:CGRectZero]; 
     emptyLabel.backgroundColor = [UIColor clearColor]; 
    } 
    return emptyLabel; 
} 
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section { 
    return [self sectionFiller]; 
} 
- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section { 
    return [self sectionFiller]; 
} 

Dieser Code wird auch die Lücke zwischen den Abschnitten die gleiche Höhe wie die Lücke vor dem ersten machen Abschnitt und die Lücke unter dem letzten. Das sieht meiner Meinung nach besser aus als der Standard, bei dem die Lücke doppelt so groß ist wie oben und unten.

+0

Nizza, danke für die Ermittlungsarbeit! –

+3

Die schonendste Methode, die ich bisher gefunden habe, ist 1 für heightForHeaderInSection und heightForFooterInSection zurückzukehren 'if ([self Tableview: Tableview numberOfRowsInSection: Abschnitt] == ​​0)' und gibt eine Ansicht mit Größe Null für 'viewForHeaderInSection' /' viewForFooterInSection 'Wenn die Zeilenanzahl 0 ist. –

+1

Danke! Vielen Dank! Verrückter Apfel. Es wäre wirklich nett, wenn sie Dinge wie die Tatsache dokumentieren würden, dass die Rückgabe von 0 für Höhen im Delegaten den Standardabstand nicht überschreibt. Es gibt viel zu viele subtile API-Randfälle, die Apple nicht dokumentiert. – smparkes

4

Diese Lösung basiert auf der Lösung user362178.Aber hält die Etiketten der Abschnitte intakt:

irgendwo definieren an der Spitze des Codes:

#define HEIGHT_FOR_HEADER_AND_FOOTER 50 

tat Last zu der Ansicht hinzufügen:

self.tableView.sectionHeaderHeight = 0; 
self.tableView.sectionFooterHeight = 0; 

Fügen Sie diese Methoden:

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section 
{ 
    // Needed because if this does not return a value, the header label of the section will 
    // be at the top of the screen. 
    if (section == 0) 
    { 
     return HEIGHT_FOR_HEADER_AND_FOOTER; 
    } 

    if ([self tableView:tableView numberOfRowsInSection:section] == 0) 
    { 
     return 0; 
    } 
    else 
    { 
     return HEIGHT_FOR_HEADER_AND_FOOTER; 
    } 
} 

- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section 
{ 
    // if last section 
    if (section == [self numberOfSectionsInTableView:tableView] - 1) 
    { 
     return HEIGHT_FOR_HEADER_AND_FOOTER; 
    } 

    return 0; 
} 
17

Hier ist die Lösung, die für mich funktioniert

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section { 
    switch (section) { 
     case 1: case 3: case 5: return 20.0f; break; 
     default: return 0.01f; // for some reason 0 is not accepted - give something :) 
    } 
} 

- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section { 
    switch (section) { 
     case 1: case 3: case 5: return 20.0f; break; 
     default: return 0.01f; // for some reason 0 is not accepted - give something :) 
    } 
} 
+1

Ich lese das und dachte "es gibt keine Möglichkeit, dass es einfach nicht 0.0f mag". Aber ich habe es überprüft und ab iOS6 ist das immer noch so. –

+0

Sogar auf iOS 8 ist 0 nicht Accepter, aber 0.01f ist :-) –

0

Der Schlüssel besteht darin, die Tabellenansicht sectionHeaderHeight und sectionFooterHeight auf Null zu setzen.

Sie können dies entweder in viewDidLoad oder in der Benutzerdefinierte Laufzeitattribute Abschnitt in Ihrem Storyboard/Xib tun. Aus irgendeinem Grund können Sie auf der Registerkarte Size Inspector die Höhe der Kopf- oder Fußzeile nicht unter 1 festlegen.

Ich habe festgestellt, dass ich, nachdem ich dies getan habe, keine anderen Delegate-Methoden auf eine besondere Weise überschreiben musste. Ich gebe einfach 0 von numberOfRowsInSection und nil von titleForHeaderInSection für Abschnitte, die leer sind, und sie nehmen keinen Platz in meiner Tabellenansicht.

Abschnitte, die Titel haben, erhalten automatisch die richtige Kopfgröße und der obere Teil der Tabellenansicht hat immer noch die Standard-Leerstelle.

1

hatte ich das gleiche Problem in iOS 7 und schließlich löste ich diese Überprüfung der Höhe für Kopf- und Fußbereich, wie Ramesh sagte:

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section { 
if ([[self.tableView objectAtIndex:section] count] == 0) 
    return 0.01f; 
else 
    return 30.f; 

}

- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section { 
return 0.01f; 

}

Es ist seltsam, aber wenn Sie die Höhe auf 0.f setzen, wird die Sektion mit einer Standardgröße angezeigt und die anderen Sektionen werden nach unten verschoben.

1

ist die eleganteste Lösung, die ich auf der Grundlage aller Antworten hier gefunden haben, sowie this answer:

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section { 

    if ([tableView.dataSource tableView:tableView numberOfRowsInSection:section] == 0) { 
     return nil; 
    } else { 
     // Return title normally 
    } 
} 

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section { 
    if ([self tableView: tableView numberOfRowsInSection: section] == 0) { 
     return 0.01f;; 
    } 

    return UITableViewAutomaticDimension; 
} 

- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section { 
    if ([self tableView: tableView numberOfRowsInSection: section] == 0) { 
     return 0.01f;; 
    } 

    return UITableViewAutomaticDimension; 
} 
Verwandte Themen