Usuń puste miejsce przed komórkami w UITableView

172

Obecnie próbuję umieścić UITableVieww innej lokalizacji, a nie u góry mojego kontrolera widoku. Powiedziawszy to, próbuje dodać nagłówek u góry, aby uwzględnić pasek nawigacji, ale nie jest to potrzebne, ponieważ nie mam na górze mojego kontrolera.

Jeśli umieszczę lewy górny róg miejsca, w UITableViewktórym chcę, aby komórki były, nie umieszcza tam komórek:

Teraz, jeśli po prostu przesunę widok tabeli w górę, aby komórki znalazły się we właściwym miejscu, pojawia się inny problem - komórki można przenosić do tego miejsca podczas przewijania (to jest moim palcem nad kontrolerem nawigacyjnym):

Kiedy odpuszczę, tak - komórki znajdą się tuż pod paskiem wyszukiwania, ale jest to oczywiście problem, w jaki sposób można je umieścić nad nim.

Jak bym to zrobił? Czy jest jakiś łatwiejszy sposób?

hetelek
źródło

Odpowiedzi:

378

Czy komórki UITableViewpokazu wyświetlają się w pustym miejscu podczas przewijania w dół?

Jeśli tak, przyczyną problemu może być wstawka dodana do elementu z UITableViewpowodu kontrolera nawigacji, który masz w widoku. Wstawka jest dodawana do widoku tabeli, aby zawartość została umieszczona poniżej paska nawigacji, gdy nie nastąpiło przewijanie. Gdy tabela jest przewijana, jej zawartość jest przewijana i wyświetlana pod przezroczystym paskiem nawigacyjnym. To zachowanie jest oczywiście pożądane tylko wtedy, gdy widok tabeli rozpoczyna się bezpośrednio pod paskiem nawigacji, co nie ma miejsca w tym przypadku.

Inną rzeczą, na którą należy zwrócić uwagę, jest to, że iOS dostosowuje wstawkę zawartości tylko dla pierwszego widoku w hierarchii widoków, jeśli jest UIScrollViewlub jest to element podrzędny (np. UITableViewI UICollectionView). Jeśli hierarchia widoków obejmuje wiele widoków przewijania, automaticallyAdjustsScrollViewInsetsdostosuje tylko pierwszy.

Oto jak zmienić to zachowanie:

a) Konstruktor interfejsu

  • Wybierz kontroler widoku
  • Otwórz inspektora atrybutów
  • W inspektorze atrybutów IB (gdy wybrany jest kontroler widoku) istnieje właściwość o nazwie „Dopasuj wstawki widoku przewijania”, która jest domyślnie włączona. Odznacz tę opcję:


    (Zdjęcie dzięki uprzejmości Dheeraj D )

Nie jestem pewien, która wersja Xcode wprowadziła tę opcję (nie zauważyłem jej w informacjach o wydaniu), ale jest ona przynajmniej dostępna w wersji 5.1.1.

Edycja: aby uniknąć nieporozumień, była to trzecia opcja wymieniona w komentarzach

b) Programowo

Dodaj to do ie viewDidLoad( podziękowania dla odpowiedzi Slavco Petkovskiego i komentarza Cris R )

// Objective-C
self.automaticallyAdjustsScrollViewInsets = NO;

// Swift
self.automaticallyAdjustsScrollViewInsets = false

c) Może to mieć znaczenie dla starszych uczniów

Możesz to naprawić, dodając

tableView.contentInset = UIEdgeInsetsZero

//Swift 3 Change
tableView.contentInset = UIEdgeInsets.zero

Lub jeśli używasz IB i pasek nawigacji nie jest przezroczysty (nie można tego stwierdzić na zrzucie ekranu)

  • Wybierz kontroler widoku
  • Otwórz inspektora atrybutów
  • W widoku Opcje kontrolera w sekcji Rozszerz krawędzie usuń zaznaczenie opcji „Pod górnymi paskami”
lekksi
źródło
2
Odznaczenie opcji „Under Top Bars” w UIView działało dobrze. Dzięki.
Andreas Øverland
Oszalałem, używając „Paging Enabled”, a przewijanie przesuwało się tylko o wysokość paska nawigacji zamiast o całą komórkę. Dzięki.
LordParsley
8
Trzecia opcja: odznacz „Dostosuj wstawki widoku przewijania” - działała jak marzenie. dzięki lekksi!
Stas Zhukovskiy
2
self.automaticallyAdjustsScrollViewInsets = false w Swift działa „de pelos”!
Cris R
1
Dzięki ustawienie UIEdgeInsetsZero jest wymagane w przypadku ponownego użycia tabeli w nowym kontrolerze tabeli za każdym razem, gdy jest on wyświetlany, w przeciwnym razie ta sama biała przerwa pojawia się i staje się coraz większa.
malhal
71

Miałem ten sam problem i jestem prawie pewien, że w pewnym momencie miałem tam UIView. Po prostu skopiowanie całego widoku tabeli, usunięcie go i ponowne wklejenie go naprawiło.

irblue
źródło
7
to jest naprawdę dziwne. To rozwiązało problem. Masz jakiś pomysł, kiedy to się stanie?
MiQUEL
Myślę, że możesz rozwiązać to o wiele łatwiej, postępując zgodnie z moją odpowiedzią z października 10'13
netshark1000
Miał ten sam problem. Usunięcie go i odczytanie również zadziałało.
sma
3
O ile wiem, wstawki zawartości widoku przewijania są dostosowywane automatycznie (jeśli automaticAdjustsScrollViewInsets = YES, którym jest domyślnie) tylko wtedy, gdy widok przewijania jest pierwszym dzieckiem w hierarchii widoku kontrolera widoku. Domyślam się, że to rozwiązanie działa, ponieważ po skopiowaniu i wklejeniu widoku tabeli nie jest to już pierwszy widok w hierarchii widoków.
lekksi
Dzieje się tak, że kiedy tableView jest pierwszą rzeczą, którą dodajesz do widoku, system uważa, że ​​musi zostawić miejsce na nawigację. Domyślam się, że niektórzy ludzie dodają tableView, a następnie headerView. Po kilku problemach usuwają następnie tableView i dodają go ponownie, co się wtedy dzieje, że headerView jest pierwszą rzeczą w hierarchii, więc system nie musi już się dostosowywać, problem został rozwiązany. Wiem, ponieważ używam tylko kodu, więc w moim przypadku musiałem dodać najpierw nagłówek, a następnie tabelę, aby to naprawić.
Lluis Gerard
40

Wybierz widok tabeli w swoim scenorysie i upewnij się, że styl jest ustawiony na „Zwykły” zamiast „Zgrupowane”. Możesz znaleźć to ustawienie w zakładce Inspektor atrybutów.

netshark1000
źródło
niesamowite… to było dla mnie dziwne rozwiązanie… Właśnie skopiowałem i wkleiłem cały kontroler widoku, ale w jakiś sposób ten wklejony kontroler widoku tableView miał ten dziwny offset. Ta odpowiedź rozwiązała mój problem
daisura99
To rozwiązało problem, ale teraz sekcje nagłówków zachowują się inaczej. Ktoś?
Bruno Muniz
Na zdrowie. Gdziekolwiek jesteś na tym świecie. Błogosławię cię na zawsze.
gabuchan
9

W moim przypadku miałem UILabel w hierarchii widoku UITableView.

Przesunąłem go „do przodu” i pojawiła się pusta przestrzeń. Nie jestem pewien dlaczego, ale działa tak, jeśli coś jest pod tableView, ukrywa puste miejsce.

Możesz także spróbować zaznaczyć / odznaczyć opcję „Dopasuj wstawki widoku przewijania” w inspektorze kontrolera widoku w scenorysie.

wprowadź opis obrazu tutaj

Andre Cytryn
źródło
2
Mam zgrupowany widok UITableView i odznaczenie opcji „Dostosuj wstawki widoku przewijania” zadziałało.
Matt,
5

ŻADNE z powyższych nie pomogło mi. ale zrobienie tego pomogło :

self.tableView.contentInset = UIEdgeInsetsMake(-64, 0, 0, 0)

zamiast „-64” możesz wpisać dowolną inną liczbę w zależności od wysokości paska nawigacji.

Tung Fam
źródło
4

Może być wstępnie dodane UIRefreshControl. Mam taki problem z kodem:

self.refreshControl = [[UIRefreshControl alloc] init];{
    [self.refreshControl setAttributedTitle:[[NSAttributedString alloc]
                                             initWithString:@"Your string"]];
    [self.refreshControl addTarget:self
                            action:@selector(updateScreen)
                  forControlEvents:UIControlEventValueChanged];

}

Jak widzisz, self.refreshControllerzaraz potem usiadłeminit

Ale jeśli ustawisz refreshControlpo konfiguracji, górna przestrzeń nie będzie ci przeszkadzać.

UIRefreshControl *refreshControl  = [[UIRefreshControl alloc] init];{
    [self.refreshControl setAttributedTitle:[[NSAttributedString alloc]
                                             initWithString:@"Your String"]];
    [self.refreshControl addTarget:self
                            action:@selector(updateScreen)
                  forControlEvents:UIControlEventValueChanged];
    self.refreshControl = refreshControl;
}
akaDuality
źródło
Nie mogę uwierzyć, że to był rzeczywisty problem. Dla mnie to tylko problem w <= 9.3.5. Jak, u licha, to rozgryzłeś?
Syreny
4

Jeśli robisz to na iOS 11, automaticAdjustsScrollViewInsets nie będzie działać, ponieważ jest przestarzały, następujący kod zadziałał dla mnie zgodnie z odpowiedzią w tym poście: https://stackoverflow.com/a/44391269/5476481

        if #available(iOS 11.0, *) {
            tblView.contentInsetAdjustmentBehavior = .never
        } else {
            automaticallyAdjustsScrollViewInsets = false
        }

Mam nadzieję że to pomoże.

Jacobo Koenig
źródło
4

W Storyboard ustaw contentInsetsswój tableviewna Nigdy

wprowadź opis obrazu tutaj

Marwen Doukh
źródło
3

Nie mogę powiedzieć na pewno, ale wygląda na to, że masz dodatkowy widok UIV, który utknął między miejscem, w którym zaczynają się komórki prototypu, a górą UITableView. Mój obraz wygląda dokładnie tak jak twój, jeśli usuniesz tekst / linie, które dodałem.

wprowadź opis obrazu tutaj

Mike S.
źródło
3

Nadal nie jestem pewien, co spowodowało to dodatkowe miejsce na górze, ale odkryłem, że usunięcie UITableView z spacją i zastąpienie go nowym zajęło to miejsce.

Musiałem przypadkowo przeciągnąć tam UIView, ale nie mogłem go wybrać, więc nie mogłem usunąć.

hetelek
źródło
3

Szybki 5

Spróbuj z usunięciem tableHeaderView i tableFooterView

var frame = CGRect.zero
frame.size.height = .leastNormalMagnitude
tblView.tableHeaderView = UIView(frame: frame)
tblView.tableFooterView = UIView(frame: frame)
Vivek
źródło
2

Sprawdź ramkę widoku tabeli w Storyboard lub XIB. Mój domyślnie ma wartość pozycji y, stąd błąd

Arthi
źródło
2

W mojej aplikacji również miałem taki problem. Ustawiłem wstawkę górnej krawędzi tableView zero. Próbowałem także ustawić falsedla automaticallyAdjustsScrollViewInsets. Ale nie zadziałało.

Wreszcie dostałem działające rozwiązanie. Nie wiem, czy to właściwy sposób. Ale implementacja heightForHeaderInSectionmetody delegata zadziałała. Aby to zadziałało, musisz zwrócić wartość niezerową (zwrócone zero wyświetli tę samą spację co poprzednio).

override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {

    return 0.1
}
Anusha Kottiyal
źródło
2

W 2017 roku działa dla mnie po prostu ta jedna linia

navigationController? .navigationBar.isTranslucent = false

Nie mam pojęcia, dlaczego to w ogóle miało na to wpływ. Może ktoś mógłby to wyjaśnić. Ale jestem prawie pewien, że to odpowiedź, której szukałaby większość ludzi.

Czas rosy
źródło
To też zrobiło to dla mnie. Dzięki!
scurioni
2

W iOS 11 i nowszych Apple zmieniło właściwość, aby dostosować wstawkę zawartości. Zastosowanie contentInsetAdjustmentBehaviori ustawić .never, aby usunąć dodatkową przestrzeń powyżej UICollectionView, UIScrollView, UITableView.

if #available(iOS 11.0, *) {

    // For scroll view
    self.scrollView.contentInsetAdjustmentBehavior = .never

    // For collection view
    self.collectionView.contentInsetAdjustmentBehavior = .never

    // For table view
    self.tableView.contentInsetAdjustmentBehavior = .never

} else {
    self.automaticallyAdjustsScrollViewInsets = false
}

Mam nadzieję, że to Ci pomoże.

Mayur Karmur
źródło
1

Cóż, dla mnie problem pojawił się, gdy przeciągnąłem komórkę prototypu z menu do widoku tabeli. Więc usunąłem to i po prostu ustawiłem komórkę prototypu na 1 we właściwościach inspektora widoku tabeli

Junaid Ahmed
źródło
1

Robię to programowo i po prostu przeniosłem mój addSubview (tableView) na dół po dodaniu wszystkich moich innych podglądów podrzędnych i rozwiązałem mój problem!

Nie jestem pewien, dlaczego pojawia się to tylko na urządzeniu, a nie w moim symulatorze, ale tak czy inaczej jest przynajmniej proste rozwiązanie!

Austin Whitelaw
źródło
1

Dopóki UITableView nie jest pierwszym widokiem podrzędnym kontrolera widoku, puste miejsce nie pojawi się.

Rozwiązanie: Dodaj ukryty / wyraźny obiekt widoku (widoki, etykiety, przycisk itp.) Jako pierwszy widok podrzędny kontrolera widoku (na tym samym poziomie co widok UITableView, ale przed nim).

jr.ong
źródło
Spędziłem tak dużo czasu, próbując to rozgryźć, wypróbowując wiele sugestii tutaj i innych postów. To jest ten, który go rozwiązał. Dziękuję Ci! Czy możesz wyjaśnić dlaczego lub opublikować link do jakiegoś dokumentu, który to robi? Właśnie uczę się programować na iOS i jest zupełnie inny niż Android! :)
Mark
0

UIView można wstawić na górze i na dole tabeli (przeciągnij i upuść). Ustaw ich właściwości jako przezroczyste i wysokość 1 piksela. Ma to na celu usunięcie dodatkowej wyściółki z przodu komórek.

Alexander
źródło
0

Miałem też ten problem, bo tableView nie był ostatnim widokiem w hierarchii. W moim przypadku miałem widok powyżej (mimo że nie zachodziły na siebie), więc przeciągnąłem go nad tableView w hierarchii i to sprawiło, że tak.

Sebyddd
źródło
0

Właśnie znalazłem na to rozwiązanie.

Po prostu wybierz widok tabeli i kliknij Edytor -> Rozmieść -> Wyślij na wierzch

To zadziałało dla mnie i mam nadzieję, że pomoże wam wszystkim.

Daniel Meza
źródło
0

W moim przypadku użyłem ContainerViewController i umieściłem w nim UITableViewController. Po usunięciu ContainerViewController. Problemy znikają.

Sandeep Ahuja
źródło
0

Błąd Xcode 8…

Spróbuj tego najpierw, jeśli styl Storyboard UITableView jest ustawiony na Plain.

Ustaw styl tabeli na Zgrupowane, a następnie z powrotem na Zwykły. Spowodowało to usunięcie miejsca w mojej aplikacji na czele mojego UITableView.

Carl
źródło
0

W moim przypadku korzystałem z widoku kontenera. (Widok główny -> Widok Contaner -> UITableView)

Wydaje mi się, że dodatkowa przestrzeń u góry przypomina obszar paska powiadomień urządzenia (gdzie wyświetlany jest czas, bateria). Naprawdę, to nie jest założenie.

To, co zrobiłem, pochodziło z UI Builder:

  • wybierz kontroler widoku tabeli zakończony
  • Otwórz inspektora atrybutów
  • Idź do -> View Controller -> Layout -> „Select Wants Full Screen”
Patricio Diego
źródło
0

Możesz użyć tego kodu do viewDidLoad lub viewDidAppear w miejscu tworzenia tabeli:

// Remove blank space on header of table view
 videoListUITableView.contentInset = UIEdgeInsetsZero;

// The iOS device = iPhone or iPod Touch
CGSize iOSDeviceScreenSize = [[UIScreen mainScreen] bounds].size;

// Set the height of the table on the basis of number of rows
videoListUITableView.frame = CGRectMake(videoListUITableView.frame.origin.x, videoListUITableView.frame.origin.y, videoListUITableView.frame.size.width, iOSDeviceScreenSize.height-100);



// Hide those cell which doesn't contain any kind of data
self.videoListUITableView.tableFooterView = [[UIView alloc] init];
Vinod Joshi
źródło
0

ustaw Rozszerzone krawędzie ViewControllera w scenorysie, tak aby underTopBarwłaściwość nie była zaznaczona.

JAHelia
źródło
0

Miał ten sam problem. Rozwiązałem to, dodając następujący element do viewDidLoad.

self.extendedLayoutIncludesOpaqueBars = true
GIJoeCodes
źródło
-1

Ustaw wstawki zawartości na zero:

sriram neelamegam
źródło
-2

sprawdzić

if ([tableView respondsToSelector:@selector(setSeparatorInset:)]) {
    [tableView setSeparatorInset:UIEdgeInsetsZero];
}
  • wspomnieć o funkcji delegata widoku tabeli cellForRowAtIndexPath:
  • może obsłużyć zarówno iOS 6, jak i 7.
Manikandan
źródło