Czy można wyłączyć pływające nagłówki w UITableView za pomocą UITableViewStylePlain?

177

Używam UITableViewdo układu „stron” zawartości. Używam nagłówków widoku tabeli do układania niektórych obrazów itp. I wolałbym, aby nie były ruchome, ale pozostawały statyczne, tak jak robią to, gdy styl jest ustawiony na UITableViewStyleGrouped.

UITableViewStyleGroupedCzy można to zrobić inaczej niż przy użyciu ? Chciałbym uniknąć używania grupowania, ponieważ dodaje margines w dół wszystkich moich komórek i wymaga wyłączenia widoku tła dla każdej z komórek. Chciałbym mieć pełną kontrolę nad moim układem. Idealnie byłoby, gdyby były to „UITableViewStyleBareBones”, ale nie widziałem tej opcji w dokumentach ...

Wielkie dzięki,

Zdradliwy
źródło
59
Użyj stylu tabeli UITableViewStyleGrouped - to odpowiedź dla wszystkich, którzy chcą wyłączyć pływające nagłówki i nie czytają całego pytania (mi się to przytrafiło ...).
przeciętny Joe
@Kasztan To rozwiązanie zerowej linii, które działa świetnie! Dzięki.
Lee Fastenau

Odpowiedzi:

27

Powinieneś móc to sfałszować, używając niestandardowej komórki do tworzenia wierszy nagłówka. Będą one następnie przewijane jak każda inna komórka w widoku tabeli.

Wystarczy dodać trochę logiki, cellForRowAtIndexPathaby zwrócić właściwy typ komórki, gdy jest to wiersz nagłówka.

Prawdopodobnie będziesz musiał sam zarządzać swoimi sekcjami, tj. Mieć wszystko w jednej sekcji i sfałszować nagłówki. (Możesz także spróbować zwrócić ukryty widok dla widoku nagłówka, ale nie wiem, czy to zadziała)

frankodwyer
źródło
11
Tak ... wydaje się jednak trochę hack. Wydaje się, że jest to przeoczenie ze strony Apple, ponieważ wyraźnie kod jest po to, aby to zrobić, musimy tylko być w stanie ustawić flagę.
Tricky
2
Sprawdź moją odpowiedź poniżej, aby uzyskać prawidłowy sposób osiągnięcia efektu bez specjalnego hackowania, po prostu zarządzaj pierwszą komórką każdej sekcji jako nagłówkiem sekcji!
Sumit Anantwar
338

Prawdopodobnie łatwiejszy sposób na osiągnięcie tego:

Cel 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);

Szybki:

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)

Nagłówki sekcji będą teraz przewijać się jak każda zwykła komórka.

samvermette
źródło
5
Ta pieprzona działa jak urok !! Obecność nagłówka widoku tabeli powoduje, że nagłówki sekcji nie zmieniają się. A niewidoczny nagłówek z odpowiednimi wstawkami zawartości tabeli załatwia sprawę ... Dziękuję bardzo! Zastanawiam się, dlaczego ta odpowiedź nie przyciąga zbyt wiele uwagi
Shyam Bhat,
4
Nadal w to nie wierz! Żadnych prywatnych interfejsów API, żadnego zagłębiania się w klasy, nic! Od wieków stykam się z tym problemem i dodawałem widoki tabeli na górze widoków przewijania (z wyłączonym przewijaniem widoku tabeli), co powodowałoby normalne przewijanie nagłówków tabeli. ale właśnie zacząłem szukać, czy firma Apple dostarczyła ostatnio jakąś nową metodę rozwiązania tego problemu ... tak się cieszę, że natknąłem się na twoją odpowiedź. jeszcze raz dzięki
Shyam Bhat
13
jedyną wadą, jaką widziałem, jest to, że górny nagłówek nie będzie już wyświetlany (można go zobaczyć tylko poprzez przewijanie w górę). Przynajmniej dla mnie to nie jest pokazane
Ruzard
5
Nadal możesz wyświetlać tableHeaderView tabeli, zwiększając jej wysokość na górze o liczbę równą wysokości nagłówka sekcji i zmniejszając wstawkę zawartości o tę samą liczbę.
Shyam Bhat
2
Chciałbym móc ponownie zagłosować za to, jestem prawie pewien, że to co najmniej trzeci raz, kiedy skończę z tym pytaniem i to rozwiązało mój problem.
Ell Neal
252

(Dla każdego, kto kiedykolwiek tu trafił z powodu złego stylu tabeli) Zmień styl tabeli z prostego na zgrupowany, za pomocą inspektora atrybutów lub kodu:

let tableView = UITableView(frame: .zero, style: .grouped)
david72
źródło
3
To jest dokładnie to, czego szukałem. Dzięki!
ninjudd
4
„Inaczej niż przy użyciu UITableViewStyleGrouped, czy istnieje sposób, aby to zrobić?”
Michael Peterson
27
Dobrze, że nauczyłem się sprawdzać wszystkie odpowiedzi przed wdrożeniem najbardziej pozytywnej odpowiedzi :)
Tung Fam
1
Oto odpowiedź, której szukałeś. Należy pamiętać, że TableView Stylewłaściwość można znaleźć również w atrybucie AttributesInspector.
Cristian Holdunu
4
Pytanie konkretnie wspomina o szukaniu sposobu „Inne niż przy użyciu UITableViewStyleGrouped”
Ferdz
73

UWAGA : to rozwiązanie implementuje zarezerwowaną metodę API. Może to uniemożliwić zatwierdzenie aplikacji przez Apple do dystrybucji w AppStore.

Opisałem metody prywatne, które zmieniają nagłówki sekcji w moim blogu

Zasadniczo wystarczy podklasować UITableViewi powrócić NOw dwóch z jego metod:

- (BOOL)allowsHeaderViewsToFloat;
- (BOOL)allowsFooterViewsToFloat;
Podkładka
źródło
40
Odpowiedź nie zasługuje na negatywną opinię tylko dlatego, że odwołuje się do prywatnych interfejsów API (nie każdy pisze kod, który ma zostać przesłany do AppStore). Jest to podwójnie prawdziwe, gdy odpowiedź jest prawidłowa. Podklasy (lub, łatwiej, tworzenie kategorii UITableView), która zwraca wartość NIE dla tych metod, zatrzymuje przepływanie nagłówków. Jeśli chcesz zobaczyć ten dodany jako publicznego API, proszę to zgłosić: bugreport.apple.com
jemmons
5
Jeśli zaimplementujemy tę funkcję w aplikacji, w jaki sposób Apple zda sobie sprawę, że używasz prywatnego interfejsu API? Z tego, co wiedzą, właśnie zaimplementowałem metodę w podklasie UITableView, a oni nawet nie mogą tego zobaczyć bez de-asemblacji kodu, a nie byłoby to takie proste. To nie jest WYWOŁANIE metody w prywatnym API, po prostu jej implementacja ....
Javier Soto
3
@jemmons, jeśli nie chcesz, żebym negatywnie ocenił twoją odpowiedź, zaznacz ją jako „Tutaj używany jest prywatny interfejs API”. Coś w rodzaju zrzeczenia się :)
kas-kad
2
Twój link „mój blog” jest uszkodzony
MartinMoizard
12
@jemmons „nie wszyscy piszą kod, który ma być przesłany do AppStore” Appstore tak naprawdę nie jest problemem. Problem polega na tym, że firma Apple może zmienić prywatne interfejsy API bez komunikowania się lub wycofywania, co spowoduje uszkodzenie aplikacji. To lepszy powód, dla którego nie powinieneś używać prywatnych interfejsów API, niż odrzucenie przez Apple
aryaxt
29

Ok, wiem, że jest późno, ale musiałem to zrobić. Spędziłem już 10 godzin na poszukiwaniu działającego rozwiązania, ale nie znalazłem pełnej odpowiedzi. Znalazłem kilka wskazówek, ale początkujących było trudnych do zrozumienia. Musiałem więc włożyć moje 2 centy i uzupełnić odpowiedź.

Jak zasugerowano w kilku odpowiedziach, jedynym działającym rozwiązaniem, które udało mi się zaimplementować, jest wstawienie normalnych komórek do widoku tabeli i traktowanie ich jako nagłówków sekcji, ale lepszym sposobem na osiągnięcie tego jest wstawienie tych komórek w wiersz 0 każdej sekcji. W ten sposób możemy bardzo łatwo obsłużyć te niestandardowe niepływające nagłówki.

Tak więc kroki są.

  1. Zaimplementuj UITableView ze stylem 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. Zaimplementuj titleForHeaderInSection jak zwykle (możesz uzyskać tę wartość za pomocą własnej logiki, ale ja wolę używać standardowych delegatów).

    - (NSString *)tableView: (UITableView *)tableView titleForHeaderInSection:(NSInteger)section
    {
        NSString *headerTitle = [sectionArray objectAtIndex:section];
        return headerTitle;
    }
  3. Immplement numberOfSectionsInTableView jak zwykle

    - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView 
    {
        int sectionCount = [sectionArray count];
        return sectionCount;
    }
  4. Zaimplementuj numberOfRowsInSection w zwykły sposób.

    - (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. Zwróć 0,0f w heightForHeaderInSection.

    - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
    {
        return 0.0f;
    }
  6. NIE implementuj viewForHeaderInSection. Całkowicie usuń metodę zamiast zwracać nil.

  7. In heightForRowAtIndexPath. Sprawdź, czy (indexpath.row == 0) i zwróć żądaną wysokość komórki dla nagłówka sekcji, w przeciwnym razie zwróć wysokość komórki.

    - (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. Teraz w cellForRowAtIndexPath sprawdź, czy (indexpath.row == 0) i zaimplementuj komórkę tak, jak chcesz, aby nagłówek sekcji był i ustaw styl zaznaczenia na none. INNYM zaimplementuj komórkę tak, jak chcesz, aby była normalna komórka.

    - (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. Teraz zaimplementuj willSelectRowAtIndexPath i zwróć nil, jeśli indexpath.row == 0. Będzie to obchodziło, że didSelectRowAtIndexPath nigdy nie zostanie wywołany dla wiersza nagłówka sekcji.

    - (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath
    {
        if (indexPath.row == 0)
        {
            return nil;
        }
    
        return indexPath;
    }
  10. Na koniec w didSelectRowAtIndexPath sprawdź, czy (indexpath.row! = 0) i kontynuuj.

    - (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
        }
    }

Z tym jesteś gotowy. Masz teraz doskonale przewijający się, niepływający nagłówek sekcji.

Sumit Anantwar
źródło
1
Zaimplementowano „willSelectRowAtIndexPath”, dzięki czemu formant nigdy nie osiągnie „didSelectRowAtIndexPath” po wybraniu wiersza nagłówka sekcji.
Sumit Anantwar
Właściwie składam + rozkładam rzędy po wybraniu nagłówka. Ale dobrze wiedzieć, że możesz to zrobić
Yariv Nissim
Świetna odpowiedź, ale dlaczego „if (indexPath.row! = 0)” sprawdza w „didSelectRowAtIndexPath”? Czy ma to być tylko dodatkowe zabezpieczenie? Wiersz nigdy nie może wynosić 0 z implementacją „willSelectRowAtIndexPath”, prawda?
Glenn85,
1
@ Glenn85, Przepraszamy za spóźnioną odpowiedź. Tak, to tylko dla dodatkowego bezpieczeństwa.
Sumit Anantwar
28

W programie Interface Builder kliknij widok tabeli problemu

widok tabeli problemów

Następnie przejdź do Attributes Inspector i zmień Style Plain na Grouped;) Easy

łatwo

HannahCarney
źródło
17

Interesującą rzeczą dotyczącą UITableViewStyleGrouped jest to, że tableView dodaje styl do komórek a nie do TableView.

Styl jest dodawany jako backgroundView do komórek jako klasa o nazwie UIGroupTableViewCellBackground, która obsługuje rysowanie innego tła w zależności od położenia komórki w sekcji.

Tak więc bardzo prostym rozwiązaniem będzie użycie UITableViewStyleGrouped, ustawienie backgroundColor tabeli na clearColor i po prostu zastąpienie backgroundView komórki w cellForRow:

cell.backgroundView = [[[UIView alloc] initWithFrame:cell.bounds] autorelease];
adamsiton
źródło
1
To powinna być najlepsza odpowiedź. Jest na ten temat wpis na blogu: corecocoa.wordpress.com/2011/09/17/…
Sam
To rozwiązanie tak naprawdę nie działa. Wokół komórek wokół celi mam dodatkową przestrzeń. Dowolny pomysł ?
gsempe
2
Czy contentView komórek nie byłby nadal przesunięty w prawo?
Piotr Tomasik
15

Zmień styl TableView:

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

Zgodnie z dokumentacją Apple dla UITableView:

UITableViewStylePlain - zwykły widok tabeli. Wszelkie nagłówki lub stopki sekcji są wyświetlane jako separatory w wierszu i przesuwają się po przewijaniu widoku tabeli.

UITableViewStyleGrouped - widok tabeli, którego sekcje przedstawiają różne grupy wierszy. Nagłówki i stopki sekcji nie są ruchome.

Aks
źródło
5

Jest inny trudny sposób. Głównym pomysłem jest podwojenie numeru sekcji, a pierwsza pokazuje tylko headerView, podczas gdy druga pokazuje rzeczywiste komórki.

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

Trzeba wtedy zaimplementować delegatów headerInSection:

- (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;
}

To podejście ma również niewielki wpływ na źródła danych:

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

W porównaniu z innymi podejściami, ten sposób jest bezpieczny bez zmiany ramki lub zawartości zestawów widoku tabeli. Mam nadzieję, że to może pomóc.

Pas ruchu
źródło
5

Najłatwiejszym sposobem uzyskania tego, czego chcesz, jest ustawienie stylu tabeli jako UITableViewStyleGrouped, styl separatora jako 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];
}

Nie próbuj zwracać widoku stopki jako nil, nie zapomnij ustawić wysokości nagłówka i widoku nagłówka, po tym, jak musisz uzyskać to, czego chcesz.

Michail Pidgorodetskiy
źródło
4

Chociaż może to nie rozwiązać twojego problemu, zrobiło to dla mnie, gdy chciałem zrobić podobną rzecz. Zamiast ustawiania nagłówka użyłem stopki z powyższej sekcji. Uratowało mnie to, że ta sekcja była mała i statyczna, więc nigdy nie przewijała się poniżej dolnej części widoku.

Torbjörn
źródło
Świetny pomysł. Uwielbiam ten hack.
Steve Moser
trochę zabawne. doceniam pomysł, ale włamanie to włamanie. nagłówki zaczęłyby unosić się na dole, więc tak naprawdę nie rozwiązuje problemu
Shyam Bhat
4

Dla Swift 3+

Po prostu użyj UITableViewStyleGroupedi ustaw wysokość stopki na zero, wykonując następujące czynności:

override func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
    return .leastNormalMagnitude
}
Tamás Sengel
źródło
1
Możesz zwrócić 0 zamiast .leastNormalMagnitude. Musisz także wdrożyćtableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView?
Ilias Karim
@IliasKarim Ustawienie go na 0 powoduje, że ma on niezerową wysokość. W viewForFooterInSectiontym przypadku nie jest też konieczne implementowanie funkcji.
Tamás Sengel
0i .leastNormalMagnitudemiał ten sam efekt. Wdrożenie viewForFooterSectionmetody jest konieczne. Powinieneś zwrócić zero. To jest w Swift 5.1 z Xcode 11.3.1.
Ilias Karim
3

Zastanawiając się, jak podejść do tego problemu, przypomniałem sobie bardzo ważny szczegół dotyczący UITableViewStyleGrouped. Sposób, w jaki UITableView implementuje zgrupowany styl (zaokrąglone obramowania wokół komórek), polega na dodaniu niestandardowego backgroundView do UITableViewCells, a nie do UITableView. Do każdej komórki dodaje się backgroundView zgodnie z jej pozycją w sekcji (górne wiersze otrzymują górną część obramowania sekcji, środkowe otrzymują krawędź boczną, a dolne - cóż, dolną część). Tak więc, jeśli chcemy tylko prostego stylu i nie mamy niestandardowego widoku tła dla naszych komórek (co ma miejsce w 90% przypadków), wszystko, co musimy zrobić, to użyć UITableViewStyleGrouped i usunąć niestandardowe tło . Można to zrobić, wykonując te dwa kroki:

Zmień nasz styl tableView na UITableViewStyleGrouped Dodaj następujący wiersz do cellForRow, tuż przed zwróceniem komórki:

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

I to wszystko. Styl tableView stanie się dokładnie taki sam, jak UITableViewStylePlain, z wyjątkiem pływających nagłówków.

Mam nadzieję że to pomoże!

James Laurenstin
źródło
2

Może mógłbyś użyć scrollViewDidScrollna tableView i zmienićcontentInset podstawie aktualnie widocznego nagłówka.

Wydaje się, że działa w moim przypadku użycia!

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)
   }
}
Jaskółka oknówka
źródło
1

Innym sposobem na zrobienie tego jest zrobienie pustej sekcji tuż przed tą, w której chcesz umieścić nagłówek, i umieszczenie nagłówka w tej sekcji. Ponieważ sekcja jest pusta, nagłówek przewinie się natychmiast.

devguydavid
źródło
1

Możesz dodać jedną sekcję (z zerowymi wierszami) powyżej, a następnie ustawić powyższą sekcję sectionFooterView jako headerView bieżącej sekcji, footerView nie jest zmienna. Mam nadzieję, że to pomoże.

Lee Lam
źródło
FooterViews pływają, tak jak HeaderViews. Po prostu unoszą się na dole ekranu, a nie na górze.
Mark A. Donohoe
0

Ignoruj ​​XAK. Nie korzystaj z prywatnych metod, jeśli chcesz, aby Twoja aplikacja miała szansę zostać zaakceptowana przez Apple.

Jest to najłatwiejsze, jeśli używasz programu Interface Builder. Dodałbyś UIView w górnej części widoku (gdzie trafią obrazy), a następnie dodaj widok tabeli poniżej. IB powinien go odpowiednio dopasować; to znaczy, że górna część widoku tabeli dotyka dołu właśnie dodanego UIView, a jego wysokość obejmuje pozostałą część ekranu.

Myślenie tutaj jest takie, że jeśli ten UIView nie jest w rzeczywistości częścią widoku tabeli, nie będzie przewijał się z widokiem tabeli. tj. zignoruj ​​nagłówek tableview.

Jeśli nie używasz konstruktora interfejsu, jest to trochę bardziej skomplikowane, ponieważ musisz uzyskać prawidłowe położenie i wysokość dla widoku tabeli.

imnk
źródło
To nie odpowiada na pytanie. Tricky odnosi się do titleHeaderViews, które są widokami, które znajdują się między komórkami, a nie do widoku nagłówka tabeli, który wydaje się sugerować.
Daniel Wood
0

Sprawdź odpowiedź, jak zaimplementować nagłówki w StoryBoard: nagłówków tabeli w StoryBoards

Zauważ też, że jeśli nie zaimplementujesz

viewForHeaderInSection:(NSInteger)section

nie będzie się unosić, co jest dokładnie tym, czego chcesz.

Raphael Oliveira
źródło
0

Aby całkowicie usunąć swobodne sekcje nagłówka sekcji, możesz to zrobić:

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

return nil nie działa.

Aby wyłączyć ruchome, ale nadal wyświetlać nagłówki sekcji, możesz zapewnić widok niestandardowy z jego własnymi zachowaniami.

djskinner
źródło
0

Odmiana rozwiązania @ 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
źródło
0

Fragment wyświetla przyklejony nagłówek tylko dla pierwszej sekcji. Inne nagłówki sekcji będą pływać z komórkami.

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
źródło
-1

Można to osiągnąć, przypisując widok nagłówka ręcznie w metodzie viewDidLoad UITableViewControllera zamiast używania viewForHeaderInSection i heightForHeaderInSection delegata. Na przykład w Twojej podklasie UITableViewController możesz zrobić coś takiego:

- (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];
}

Widok nagłówka zniknie wtedy, gdy użytkownik przewinie. Nie wiem, dlaczego to działa w ten sposób, ale wydaje się, że osiąga to, czego szukasz.

Johnny Oshika
źródło
To nie jest dla sekcji, to jest dla 1 nagłówka na górze.
makdad,
-1

Może możesz po prostu ustawić przezroczyste tło widoku nagłówka:

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

Lub zastosuj globalnie:

    [UITableViewHeaderFooterView appearance].tintColor = [UIColor clearColor];
Tinpont
źródło
-2

Mam inne, jeszcze prostsze rozwiązanie, do użycia bez autoukładu i ze wszystkim wykonanym przez XIB:

1 / Umieść nagłówek w widoku tabeli, przeciągając go i upuszczając bezpośrednio w widoku tabeli.

2 / W Inspektorze rozmiaru nowo utworzonego nagłówka, po prostu zmień jego autodopasowanie: powinieneś pozostawić tylko górną, lewą i prawą kotwicę oraz wypełnienie w poziomie.

Tak powinno być ustawione dla nagłówka

To powinno załatwić sprawę!

CyberDandy
źródło
-2

Zgodnie z odpowiedzią @ samvermette , Powyższy kod zaimplementowałem w języku Swift, aby ułatwić programistom korzystanie z niego.

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
źródło
-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
}

Pomogło to wykorzystać przestrzeń nagłówka

Pratik
źródło
Proszę, nie rób tego🙏
MQoder
-3

Najnowsza aktualizacja 2020

Przetestowano za pomocą Xcode 14.

Aby ukryć dowolny nagłówek sekcji, Zwróć nil jako tytuł delegata sekcji

func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
    return nil
}
Saranjith
źródło
-4

można to łatwo osiągnąć, implementując metodę viewForHeaderInSection w klasie delegata tableview. ta metoda oczekuje UIView jako obiektu zwracanego (który jest widokiem nagłówka). zrobiłem to samo w swoim kodzie

Raj
źródło
Oryginalny plakat nie wymaga niestandardowego nagłówka. Chcą nagłówka, który nie „pływa” na górze tabeli. Twoja sugestia wciąż się pojawia.
jemmons
zmień widok tabeli na UITableViewStyleGrouped z viewforheader, a następnie zatrzyma go
mskw