Ist es möglich, schwebende Header in UITableView mit UITableViewStylePlain zu deaktivieren?

177

Ich verwende ein, UITableViewum Inhaltsseiten zu gestalten. Ich verwende die Überschriften der Tabellenansicht, um bestimmte Bilder usw. zu gestalten, und ich würde es vorziehen, wenn sie nicht schweben, sondern statisch bleiben, wie sie es tun, wenn der Stil eingestellt ist UITableViewStyleGrouped.

Gibt UITableViewStyleGroupedes eine andere Möglichkeit, als dies zu tun? Ich möchte die Verwendung von gruppiert vermeiden, da dadurch ein Rand für alle meine Zellen hinzugefügt wird und die Hintergrundansicht für jede der Zellen deaktiviert werden muss. Ich möchte die volle Kontrolle über mein Layout haben. Im Idealfall handelt es sich um "UITableViewStyleBareBones", aber ich habe diese Option in den Dokumenten nicht gesehen ...

Danke vielmals,

Tricky
quelle
59
Verwenden Sie den Tabellenstil UITableViewStyleGrouped - dies ist die Antwort für alle, die schwebende Header deaktivieren und nicht die gesamte Frage lesen möchten (mir ist es passiert ...).
Durchschnitt Joe
@ Kasztan Dies ist eine Nulllinienlösung, die großartig funktioniert! Vielen Dank.
Lee Fastenau

Antworten:

27

Sie sollten in der Lage sein, dies zu fälschen, indem Sie eine benutzerdefinierte Zelle verwenden, um Ihre Kopfzeilen zu erstellen. Diese scrollen dann wie jede andere Zelle in der Tabellenansicht.

Sie müssen nur eine Logik hinzufügen cellForRowAtIndexPath, um den richtigen Zelltyp zurückzugeben, wenn es sich um eine Kopfzeile handelt.

Sie müssen Ihre Abschnitte wahrscheinlich selbst verwalten, dh alles in einem Abschnitt haben und die Überschriften fälschen. (Sie können auch versuchen, eine ausgeblendete Ansicht für die Header-Ansicht zurückzugeben, aber ich weiß nicht, ob dies funktioniert.)

frankodwyer
quelle
11
Ja ... es scheint allerdings ein bisschen hackig zu sein. Dies scheint ein Versehen eines Apple-Teils zu sein, da der Code eindeutig dazu da ist, müssen wir nur in der Lage sein, ein Flag zu setzen.
Tricky
2
Überprüfen Sie meine Antwort unten auf den richtigen Weg, um den Effekt ohne speziellen Hack zu erzielen. Verwalten Sie einfach die erste Zelle jedes Abschnitts als Abschnittsüberschrift!
Sumit Anantwar
338

Ein wahrscheinlich einfacher Weg, dies zu erreichen:

Ziel c:

CGFloat dummyViewHeight = 40;
UIView *dummyView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.tableView.bounds.size.width, dummyViewHeight)];
self.tableView.tableHeaderView = dummyView;
self.tableView.contentInset = UIEdgeInsetsMake(-dummyViewHeight, 0, 0, 0);

Schnell:

let dummyViewHeight = CGFloat(40)
self.tableView.tableHeaderView = UIView(frame: CGRect(x: 0, y: 0, width: self.tableView.bounds.size.width, height: dummyViewHeight))
self.tableView.contentInset = UIEdgeInsetsMake(-dummyViewHeight, 0, 0, 0)

Abschnittsüberschriften werden jetzt wie in jeder normalen Zelle gescrollt.

Samvermette
quelle
5
Dieser verdammte wirkt wie ein Zauber !! Das Vorhandensein eines Tabellenkopf-Ansichtskopfs verhindert, dass die Abschnittsüberschriften schweben. Und ein unsichtbarer Header mit entsprechenden Inhaltseinfügungen für die Tabelle macht den Trick. Vielen Dank! Ich frage mich, warum diese Antwort nicht viel Aufmerksamkeit erhält
Shyam Bhat
4
Glaube es immer noch nicht! Keine privaten APIs, kein Eingraben in die Klassen, nichts! Ich bin seit Ewigkeiten mit diesem Problem konfrontiert und habe Tabellenansichten über Bildlaufansichten hinzugefügt (mit deaktiviertem Bildlauf in der Tabellenansicht), wodurch die Tabellenüberschriften normal gescrollt würden. Aber ich habe gerade angefangen zu suchen, ob Apple in letzter Zeit neue Methoden zur Behebung dieses Problems bereitgestellt hat. Ich bin so froh, dass ich auf Ihre Antwort gestoßen bin.
Nochmals vielen
13
Der einzige Nachteil, den ich gesehen habe, ist, dass der obere Header nicht mehr angezeigt wird (Sie können ihn nur durch Scrollen nach oben sehen). Zumindest für mich wird es nicht gezeigt
Ruzard
5
Sie können die tableHeaderView der Tabelle weiterhin anzeigen, indem Sie die Höhe oben um eine Zahl erhöhen, die der Höhe der Abschnittsüberschrift entspricht, und den Inhalt um dieselbe Zahl reduzieren.
Shyam Bhat
2
Ich wünschte, ich könnte dies noch einmal verbessern. Ich bin mir ziemlich sicher, dass dies mindestens das dritte Mal ist, dass ich mich mit dieser Frage befasse, und dies hat mein Problem gelöst.
Ell Neal
250

(Für alle, die aufgrund eines falschen Tabellenstils hierher gekommen sind) Ändern Sie den Tabellenstil von einfach in gruppiert, über den Attributinspektor oder über den Code:

let tableView = UITableView(frame: .zero, style: .grouped)
david72
quelle
3
Genau das habe ich gesucht. Vielen Dank!
Ninjudd
4
"Gibt es eine andere Möglichkeit, als UITableViewStyleGrouped zu verwenden?"
Michael Peterson
26
Gut, dass ich gelernt habe, alle Antworten zu überprüfen, bevor ich die am besten bewertete implementiere :)
Tung Fam
1
Das ist die Antwort, nach der Sie gesucht haben. Beachten Sie, dass Sie die TableView StyleEigenschaft auch im AttributesInspector finden.
Cristian Holdunu
4
Die Frage erwähnt ausdrücklich, nach einem Weg zu suchen "Andere als mit UITableViewStyleGrouped"
Ferdz
74

WARNUNG : Diese Lösung implementiert eine reservierte API-Methode. Dies könnte verhindern, dass die App von Apple für die Verteilung im AppStore genehmigt wird.

Ich habe die privaten Methoden beschrieben, mit denen Abschnittsüberschriften in meinem Blog schweben

Grundsätzlich müssen Sie nur zwei seiner Methoden unterordnen UITableViewund zurückgeben NO:

- (BOOL)allowsHeaderViewsToFloat;
- (BOOL)allowsFooterViewsToFloat;
Shim
quelle
40
Eine Antwort verdient keine Ablehnung, nur weil sie auf private APIs verweist (nicht jeder schreibt Code, der an den AppStore gesendet werden soll). Dies gilt in zweifacher Hinsicht, wenn die Antwort richtig ist. Eine Unterklasse (oder einfacher eine UITableView-Kategorie), die für diese Methoden NO zurückgibt, verhindert, dass Header schweben. Wenn Sie möchten, dass dies als öffentliche API hinzugefügt wird, reichen
jemmons
5
Wenn wir diese Funktion in einer App implementieren, wie würde Apple erkennen, dass Sie eine private API verwenden? Nach allem, was sie wissen, habe ich gerade eine Methode in einer Unterklasse von UITableView implementiert, und sie können das nicht einmal sehen, ohne den Code zu zerlegen, und es wäre nicht so einfach. Es ruft keine Methode in einer privaten API auf, es implementiert nur eine ...
Javier Soto
3
@jemmons Wenn Sie nicht möchten, dass ich Ihre Antwort ablehne, markieren Sie sie als "private API wird hier verwendet". Art von Haftungsausschluss :)
Kas-Kad
2
Ihr "mein Blog" -Link ist defekt
MartinMoizard
12
@jemmons "Nicht jeder schreibt Code, der an den AppStore gesendet werden soll" Appstore ist nicht wirklich das Problem. Das Problem ist, dass Apple die privaten APIs ändern kann, ohne zu kommunizieren oder zu verwerfen, wodurch Ihre App beschädigt wird. Das ist ein besserer Grund, warum Sie keine privaten APIs verwenden sollten, als von Apple abgelehnt zu werden
aryaxt
29

Ok, ich weiß, dass es spät ist, aber ich musste es tun. Ich habe inzwischen 10 Stunden nach einer funktionierenden Lösung gesucht, aber keine vollständige Antwort gefunden. Habe einige Hinweise gefunden, aber für den Anfang schwer zu verstehen. Also musste ich meine 2 Cent eingeben und die Antwort vervollständigen.

Wie in den wenigen Antworten vorgeschlagen, war die einzige funktionierende Lösung, die ich implementieren konnte, das Einfügen normaler Zellen in die Tabellenansicht und deren Behandlung als Abschnittsüberschriften. Der bessere Weg, dies zu erreichen, ist das Einfügen dieser Zellen bei Zeile 0 jedes Abschnitts. Auf diese Weise können wir diese benutzerdefinierten nicht schwebenden Header sehr einfach verarbeiten.

Die Schritte sind also.

  1. Implementieren Sie UITableView mit dem Stil UITableViewStylePlain.

    -(void) loadView
    {
        [super loadView];
    
        UITableView *tblView =[[UITableView alloc] initWithFrame:CGRectMake(0, frame.origin.y, frame.size.width, frame.size.height-44-61-frame.origin.y) style:UITableViewStylePlain];
        tblView.delegate=self;
        tblView.dataSource=self;
        tblView.tag=2;
        tblView.backgroundColor=[UIColor clearColor];
        tblView.separatorStyle = UITableViewCellSeparatorStyleNone;
    }
  2. Implementieren Sie titleForHeaderInSection wie gewohnt (Sie können diesen Wert mithilfe Ihrer eigenen Logik abrufen, ich bevorzuge jedoch die Verwendung von Standarddelegierten).

    - (NSString *)tableView: (UITableView *)tableView titleForHeaderInSection:(NSInteger)section
    {
        NSString *headerTitle = [sectionArray objectAtIndex:section];
        return headerTitle;
    }
  3. Implementieren Sie numberOfSectionsInTableView wie gewohnt

    - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView 
    {
        int sectionCount = [sectionArray count];
        return sectionCount;
    }
  4. Implementieren Sie numberOfRowsInSection wie gewohnt.

    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 
    {
        int rowCount = [[cellArray objectAtIndex:section] count];
        return rowCount +1; //+1 for the extra row which we will fake for the Section Header
    }
  5. Geben Sie 0.0f in heightForHeaderInSection zurück.

    - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
    {
        return 0.0f;
    }
  6. Implementieren Sie NICHT viewForHeaderInSection. Entfernen Sie die Methode vollständig, anstatt Null zurückzugeben.

  7. In heightForRowAtIndexPath. Überprüfen Sie, ob (indexpath.row == 0) und geben Sie die gewünschte Zellenhöhe für den Abschnittskopf zurück, andernfalls geben Sie die Höhe der Zelle zurück.

    - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        if(indexPath.row == 0)
        {
            return 80; //Height for the section header
        }
        else
        {
            return 70; //Height for the normal cell
        }
    }
  8. Überprüfen Sie nun in cellForRowAtIndexPath, ob (indexpath.row == 0), und implementieren Sie die Zelle so, wie der Abschnittskopf sein soll, und setzen Sie den Auswahlstil auf none. Andernfalls implementieren Sie die Zelle so, wie Sie es von der normalen Zelle erwarten.

    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        if (indexPath.row == 0)
        {
            UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"SectionCell"];
            if (cell == nil)
            {
                cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"SectionCell"] autorelease];
                cell.selectionStyle = UITableViewCellSelectionStyleNone; //So that the section header does not appear selected
    
                cell.backgroundView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"SectionHeaderBackground"]];
            }
    
            cell.textLabel.text = [tableView.dataSource tableView:tableView titleForHeaderInSection:indexPath.section];
    
            return cell;
        }
        else
        {
            UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell"];
    
            if (cell == nil) 
            {
                cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"Cell"] autorelease];
                cell.selectionStyle = UITableViewCellSelectionStyleGray; //So that the normal cell looks selected
    
                cell.backgroundView =[[[UIImageView alloc] initWithImage:[UIImage imageNamed:@"CellBackground"]]autorelease];
                cell.selectedBackgroundView=[[[UIImageView alloc] initWithImage:[UIImage imageNamed:@"SelectedCellBackground"]] autorelease];
            }
    
            cell.textLabel.text = [[cellArray objectAtIndex:indexPath.section] objectAtIndex:indexPath.row -1]; //row -1 to compensate for the extra header row
    
            return cell;
        }
    }
  9. Implementieren Sie nun willSelectRowAtIndexPath und geben Sie nil zurück, wenn indexpath.row == 0. Dies wird dafür sorgen, dass didSelectRowAtIndexPath niemals für die Abschnittsheaderzeile ausgelöst wird.

    - (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath
    {
        if (indexPath.row == 0)
        {
            return nil;
        }
    
        return indexPath;
    }
  10. Überprüfen Sie schließlich in didSelectRowAtIndexPath, ob (indexpath.row! = 0), und fahren Sie fort.

    - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
    {
        if (indexPath.row != 0)
        {
            int row = indexPath.row -1; //Now use 'row' in place of indexPath.row
    
            //Do what ever you want the selection to perform
        }
    }

Damit sind Sie fertig. Sie haben jetzt eine perfekt scrollende, nicht schwebende Abschnittsüberschrift.

Sumit Anantwar
quelle
1
'WillSelectRowAtIndexPath' wurde implementiert, sodass das Steuerelement bei Auswahl der Abschnittskopfzeile nie 'didSelectRowAtIndexPath' erreicht.
Sumit Anantwar
Eigentlich falte ich die Zeilen, wenn der Header ausgewählt ist. Aber gut zu wissen, dass Sie das können
Yariv Nissim
Tolle Antwort, aber warum das 'if (indexPath.row! = 0)' in 'didSelectRowAtIndexPath' einchecken? Ist es nur, um besonders sicher zu sein? Die Zeile kann mit Ihrer 'willSelectRowAtIndexPath'-Implementierung niemals 0 sein, oder?
Glenn85
1
@ Glenn85, Entschuldigung für die späte Antwort. Ja, es ist nur für eine zusätzliche Sicherheit.
Sumit Anantwar
28

Klicken Sie in Ihrem Interface Builder auf Ihre Problemtabellenansicht

Problemtabellenansicht

Navigieren Sie dann zu Attributes Inspector und ändern Sie Style Plain in Grouped;) Easy

einfach

HannahCarney
quelle
17

Das Interessante an UITableViewStyleGrouped ist, dass die tableView den Zellen den Stil hinzufügt und nicht der TableView.

Der Stil wird den Zellen als Hintergrundansicht als Klasse mit dem Namen UIGroupTableViewCellBackground hinzugefügt, die das Zeichnen unterschiedlicher Hintergründe entsprechend der Position der Zelle im Abschnitt behandelt.

Eine sehr einfache Lösung besteht darin, UITableViewStyleGrouped zu verwenden, die Hintergrundfarbe der Tabelle auf clearColor zu setzen und einfach die Hintergrundansicht der Zelle in cellForRow zu ersetzen:

cell.backgroundView = [[[UIView alloc] initWithFrame:cell.bounds] autorelease];
Adamsiton
quelle
1
Dies sollte die beste Antwort sein. Es gibt einen Blog-Beitrag darüber hier: corecocoa.wordpress.com/2011/09/17/…
Sam
Diese Lösung funktioniert nicht wirklich. Ich bekomme immer mehr Platz in den Zellen. Irgendeine Idee ?
Gsempe
2
Würde die Inhaltsansicht der Zellen nicht immer noch nach rechts verschoben?
Piotr Tomasik
15

Ändern Sie Ihren TableView-Stil:

self.tableview = [[UITableView alloc] initwithFrame:frame style:UITableViewStyleGrouped];

Gemäß Apple-Dokumentation für UITableView:

UITableViewStylePlain- Eine einfache Tabellenansicht. Alle Kopf- oder Fußzeilen von Abschnitten werden als Inline-Trennzeichen angezeigt und schweben, wenn die Tabellenansicht gescrollt wird.

UITableViewStyleGrouped- Eine Tabellenansicht, deren Abschnitte unterschiedliche Gruppen von Zeilen darstellen. Die Kopf- und Fußzeilen des Abschnitts schweben nicht.

Aks
quelle
5

Es gibt noch einen anderen schwierigen Weg. Die Hauptidee besteht darin, die Abschnittsnummer zu verdoppeln, und die erste zeigt nur die Header-Ansicht, während die zweite die realen Zellen zeigt.

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return sectionCount * 2;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    if (section%2 == 0) {
        return 0;
    }
    return _rowCount;
}

Was dann zu tun ist, ist die Implementierung der headerInSection-Delegaten:

- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
    if (section%2 == 0) {
        //return headerview;
    }
    return nil;
}

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
    if (section%2 == 0) {
        //return headerheight;
    }
    return 0;
}

Dieser Ansatz hat auch nur geringe Auswirkungen auf Ihre Datenquellen:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    int real_section = (int)indexPath.section / 2;
    //your code
}

Im Vergleich zu anderen Ansätzen ist dieser Weg sicher, ohne den Frame oder die contentInsets der Tabellenansicht zu ändern. Hoffe das kann helfen.

Fahrbahn
quelle
5

Der einfachste Weg, um das zu bekommen, was Sie wollen, besteht darin, Ihren Tabellenstil wie folgt UITableViewStyleGroupedfestzulegen UITableViewCellSeparatorStyleNone:

- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {
    return CGFLOAT_MIN; // return 0.01f; would work same 
}

- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section {
    return [[UIView alloc] initWithFrame:CGRectZero];
}

Versuchen Sie nicht, die Fußzeilenansicht zurückzugeben, da nilSie die Kopfzeilenhöhe und die Kopfzeilenansicht nicht vergessen haben, nachdem Sie das gewünschte Ergebnis erhalten haben.

Michail Pidgorodetskiy
quelle
4

Obwohl dies Ihr Problem möglicherweise nicht löst, war es für mich der Fall, als ich etwas Ähnliches tun wollte. Anstatt die Kopfzeile zu setzen, habe ich die Fußzeile des obigen Abschnitts verwendet. Was mich gerettet hat, war, dass dieser Abschnitt klein und statisch war und daher nie unter den unteren Rand der Ansicht gescrollt wurde.

Torbjörn
quelle
Großartige Idee. Ich liebe diesen Hack.
Steve Moser
irgendwie lustig. Ich schätze die Idee, aber ein Hack ist ein Hack. Die Header würden unten schweben, so dass das Problem nicht wirklich gelöst wird
Shyam Bhat
4

Für Swift 3+

Verwenden Sie einfach UITableViewStyleGroupeddie Fußzeile und setzen Sie sie wie folgt auf Null:

override func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
    return .leastNormalMagnitude
}
Tamás Sengel
quelle
1
Sie können 0 statt zurückgeben .leastNormalMagnitude. Auch müssen Sie implementierentableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView?
Ilias Karim
@IliasKarim Wenn Sie den Wert auf 0 setzen, wird eine Höhe ungleich Null angezeigt. viewForFooterInSectionIn diesem Fall ist es auch nicht erforderlich, die Funktion zu implementieren .
Tamás Sengel
0und .leastNormalMagnitudehatte den gleichen Effekt. Die Implementierung der viewForFooterSectionMethode ist erforderlich. Sie sollten null zurückgeben. Dies ist auf Swift 5.1 mit Xcode 11.3.1.
Ilias Karim
3

Während ich darüber nachdachte, wie ich dieses Problem angehen sollte, erinnerte ich mich an ein sehr wichtiges Detail von UITableViewStyleGrouped. Die Art und Weise, wie UITableView den gruppierten Stil (die abgerundeten Ränder um die Zellen) implementiert, besteht darin, den UITableViewCells eine benutzerdefinierte Hintergrundansicht und nicht der UITableView hinzuzufügen. Jeder Zelle wird eine Hintergrundansicht entsprechend ihrer Position im Abschnitt hinzugefügt (obere Reihen erhalten den oberen Teil des Abschnittsrandes, mittlere den seitlichen Rand und der untere Teil - nun, den unteren Teil). Wenn wir also nur einen einfachen Stil möchten und keine benutzerdefinierte Hintergrundansicht für unsere Zellen haben (was in 90% der Fälle der Fall ist), müssen wir nur UITableViewStyleGrouped verwenden und den benutzerdefinierten Hintergrund entfernen . Dies kann durch Ausführen der beiden folgenden Schritte erfolgen:

Ändern Sie unseren tableView-Stil in UITableViewStyleGrouped. Fügen Sie cellForRow die folgende Zeile hinzu, bevor wir die Zelle zurückgeben:

cell.backgroundView = [[[UIView alloc] initWithFrame: cell.bounds] autorelease];

Und das ist es. Der tableView-Stil wird mit Ausnahme der schwebenden Header genau wie UITableViewStylePlain.

Hoffe das hilft!

James Laurenstin
quelle
2

Vielleicht könnten Sie scrollViewDidScrollauf der tableView verwenden und die änderncontentInset basierend auf dem aktuell sichtbaren Header .

Es scheint für meinen Anwendungsfall zu funktionieren!

extension ViewController : UIScrollViewDelegate{

    func scrollViewDidScroll(_ scrollView: UIScrollView) {
        guard   let tableView = scrollView as? UITableView,
            let visible = tableView.indexPathsForVisibleRows,
            let first = visible.first else {
            return
        }

        let headerHeight = tableView.rectForHeader(inSection: first.section).size.height
        let offset =  max(min(0, -tableView.contentOffset.y), -headerHeight)
        self.tableView.contentInset = UIEdgeInsetsMake(offset, 0, -offset, 0)
   }
}
Martin
quelle
1

Eine andere Möglichkeit besteht darin, einen leeren Abschnitt direkt vor dem zu erstellen, auf dem die Überschrift angezeigt werden soll, und die Überschrift auf diesen Abschnitt zu setzen. Da der Abschnitt leer ist, wird die Kopfzeile sofort gescrollt.

devguydavid
quelle
1

Sie können oben einen Abschnitt (mit null Zeilen) hinzufügen und dann den obigen AbschnittFooterView als HeaderView des aktuellen Abschnitts festlegen. FooterView schwebt nicht. Hoffe es gibt eine Hilfe.

Lee Lam
quelle
FooterViews schweben genau wie HeaderViews. Sie schweben nur am unteren Rand des Bildschirms, nicht oben.
Mark A. Donohoe
0

XAK ignorieren. Erforschen Sie keine privaten Methoden, wenn Sie möchten, dass Ihre App von Apple akzeptiert wird.

Dies ist am einfachsten, wenn Sie Interface Builder verwenden. Sie würden eine UIView oben in der Ansicht hinzufügen (wohin die Bilder gehen) und dann Ihre Tabellenansicht darunter hinzufügen. IB sollte es entsprechend dimensionieren; Das heißt, der obere Rand der Tabellenansicht berührt den unteren Rand des gerade hinzugefügten UIView und seine Höhe deckt den Rest des Bildschirms ab.

Der Gedanke hier ist, dass wenn diese UIView nicht tatsächlich Teil der Tabellenansicht ist, sie nicht mit der Tabellenansicht scrollen wird. dh ignorieren Sie den Tableview-Header.

Wenn Sie den Interface Builder nicht verwenden, ist dies etwas komplizierter, da Sie die richtige Position und Höhe für die Tabellenansicht festlegen müssen.

imnk
quelle
Dies beantwortet die Frage nicht. Tricky bezieht sich auf die titleHeaderViews, bei denen es sich um die Ansichten handelt, die sich zwischen den Zellen befinden, und nicht auf die Tabellenkopfansicht, die Sie anscheinend vorschlagen.
Daniel Wood
0

Überprüfen Sie die Antwort zum Implementieren von Headern mit StoryBoard: Tabellenkopfansichten in StoryBoards

Beachten Sie auch, dass, wenn Sie nicht implementieren

viewForHeaderInSection:(NSInteger)section

es wird nicht schweben, was genau das ist, was Sie wollen.

Raphael Oliveira
quelle
0

Gehen Sie folgendermaßen vor, um die Header-Abschnitte für schwebende Abschnitte vollständig zu entfernen:

- (UIView *) tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
    return [[UIView alloc] init];
}

return nil funktioniert nicht

Um das Floating zu deaktivieren, aber dennoch Abschnittsüberschriften anzuzeigen, können Sie eine benutzerdefinierte Ansicht mit eigenen Verhaltensweisen bereitstellen.

djskinner
quelle
0

Eine Variation der Lösung von @ samvermette:

/// Allows for disabling scrolling headers in plain-styled tableviews
extension UITableView {

    static let shouldScrollSectionHeadersDummyViewHeight = CGFloat(40)

    var shouldScrollSectionHeaders: Bool {
        set {
            if newValue {
                tableHeaderView = UIView(frame: CGRect(x: 0, y: 0, width: bounds.size.width, height: UITableView.shouldScrollSectionHeadersDummyViewHeight))
                contentInset = UIEdgeInsets(top: -UITableView.shouldScrollSectionHeadersDummyViewHeight, left: 0, bottom: 0, right: 0)
            } else {
                tableHeaderView = nil
                contentInset = .zero
            }
        }

        get {
            return tableHeaderView != nil && contentInset.top == UITableView.shouldScrollSectionHeadersDummyViewHeight
        }
    }

}
raf
quelle
0

Das Snippet zeigt nur für den ersten Abschnitt einen klebrigen Header an. Andere Abschnittsüberschriften schweben mit einer Zelle.

func tableView(_ tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int) {

    if section == 1 {
        tableView.contentInset = .zero
    }

}

func tableView(_ tableView: UITableView, didEndDisplayingHeaderView view: UIView, forSection section: Int) {
    if section == 0 {
        tableView.contentInset = .init(top: -tableView.sectionHeaderHeight, left: 0, bottom: 0, right: 0)
    }
}
Adobels
quelle
-1

Dies kann erreicht werden, indem die Header-Ansicht manuell in der viewDidLoad-Methode des UITableViewController zugewiesen wird, anstatt die viewForHeaderInSection und heightForHeaderInSection des Delegaten zu verwenden. In Ihrer Unterklasse von UITableViewController können Sie beispielsweise Folgendes tun:

- (void)viewDidLoad {
    [super viewDidLoad];

    UILabel *headerView = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 0, 40)];
    [headerView setBackgroundColor:[UIColor magentaColor]];
    [headerView setTextAlignment:NSTextAlignmentCenter];
    [headerView setText:@"Hello World"];
    [[self tableView] setTableHeaderView:headerView];
}

Die Kopfzeilenansicht verschwindet dann, wenn der Benutzer einen Bildlauf durchführt. Ich weiß nicht, warum das so funktioniert, aber es scheint zu erreichen, was Sie tun möchten.

Johnny Oshika
quelle
Dies ist nicht für einen Abschnitt, sondern für 1 Kopfzeile oben.
Makdad
-1

Vielleicht können Sie den Hintergrund der Kopfzeile einfach transparent machen:

- (void)tableView:(UITableView *)tableView willDisplayHeaderView:(UIView *)view forSection:(NSInteger)section {
    view.tintColor = [UIColor clearColor];
}

Oder wenden Sie es global an:

    [UITableViewHeaderFooterView appearance].tintColor = [UIColor clearColor];
Tinpont
quelle
-2

Ich habe eine andere, noch einfachere Lösung, die ohne Autolayout und mit allem, was über XIB erledigt wird, verwendet werden kann:

1 / Fügen Sie Ihre Kopfzeile in die Tabellenansicht ein, indem Sie sie direkt in die Tabellenansicht ziehen und dort ablegen.

2 / Ändern Sie im Größeninspektor des neu erstellten Headers einfach die automatische Größe: Sie sollten nur den oberen, linken und rechten Anker sowie die Füllung horizontal lassen.

So sollte es für den Header eingestellt werden

Das sollte den Trick machen!

CyberDandy
quelle
-2

Laut der Antwort von @ samvermette , Ich habe den obigen Code in Swift implementiert, um Codierern die Verwendung von Swift zu erleichtern.

let dummyViewHeight = CGFloat(40)
self.tableView.tableHeaderView = UIView(frame: CGRect(x: 0, y: 0, width: self.tableView.bounds.size.width, height: dummyViewHeight))
self.tableView.contentInset = UIEdgeInsetsMake(-dummyViewHeight, 0, 0, 0)
Bingerz
quelle
-2

Ref: https://stackoverflow.com/a/26306212

let tableView = UITableView(frame: .zero, style: .grouped)

PLUSE

func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
    if section == 0 {
        return 40
    }else{
        tableView.sectionHeaderHeight = 0
    }

    return 0
}

Dies half, den Header-Platz zu nutzen

Pratik
quelle
Bitte tun Sie das nicht
MQoder
-3

2020 Neuestes Update

Getestet mit Xcode 14.

Um einen Abschnittskopf auszublenden, geben Sie nil als Titel des Abschnittsdelegierten zurück

func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
    return nil
}
Saranjith
quelle
-4

Sie können dies leicht erreichen, indem Sie die viewForHeaderInSection-Methode in der tableview-Delegatenklasse implementieren. Diese Methode erwartet eine UIView als Rückgabeobjekt (dies ist Ihre Header-Ansicht). Ich habe das gleiche in meinem Code getan

Raj
quelle
Das Originalposter möchte keinen benutzerdefinierten Header. Sie wollen einen Header, der nicht oben in der Tabelle "schwebt". Ihr Vorschlag schwebt immer noch.
Jemmons
Ändern Sie die Tabellenansicht in UITableViewStyleGrouped mit viewforheader, dann wird es gestoppt
mskw