iOS8 - ograniczenia niejednoznacznie sugerują wysokość zero

100

Czy ktoś ma pomysł, jak to debugować?

Ostrzeżenie tylko raz: wykryto przypadek, w którym ograniczenia niejednoznacznie sugerują wysokość zerową dla widoku zawartości komórki tabeli. Rozważamy zawalenie się niezamierzone i zamiast tego używamy standardowej wysokości.

Wiersze mają stałą wysokość określoną przez

- (CGFloat)tableView:(UITableView *)tableView 
           heightForRowAtIndexPath:(NSIndexPath *)indexPath{
   return 34.0;
}

I wszyscy constraintswydają się być szczęśliwi ...

Chris
źródło

Odpowiedzi:

129

Wymuszenie wysokości powrotu i szacowanej wysokości sprawiło, że ostrzeżenie zniknęło w moim przypadku.

- (CGFloat)tableView:(UITableView *)tableView 
           estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath {
    return 44;
}

- (CGFloat)tableView:(UITableView *)tableView 
           heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    return 44;
}

Innym rozwiązaniem, w którym nie potrzebujesz tych dwóch przesłonięć, jest po prostu użycie self.tableView.rowHeight = 44;w loadViewmetodzie lub init.

FBronner
źródło
1
Mam wiele wierszy typu w sekcji i tylko jeden z nich ma dynamiczną wysokość. to nie działa
Raj Aggrawal
Jeśli ustawimy domyślną wysokość w xib / storyboard, nie musimy implementować tych metod.
Satyam
77

Można również dodać ograniczenia pionowe od góry do dołu widoku zawartości. To sprawi, że autoukład będzie szczęśliwy (ponieważ teraz wie, jak sam obliczyć wysokość komórki).

MonsieurDart
źródło
2
To zadziałało dla mnie. Przeszedłem przez wszystkie komórki kontenera i upewniłem się, że co najmniej jeden widok podrzędny ma zarówno ograniczenie „górna przestrzeń do kontenera”, jak i „dolna przestrzeń do kontenera”.
Rog182
7
To właściwa odpowiedź na iOS 8, gdy używasz samoczynnie zmieniających się rozmiarów komórek widoku tabeli.
tsafrir
1
Czy masz na myśli ograniczenia od elementów wewnątrz widoku zawartości do góry i dołu widoku zawartości?
Zack Shapiro,
Próbowałem tego, ale wciąż otrzymuję ostrzeżenie o sprzecznych ograniczeniach.
Shirish Kumar
2
Upewnij się, że dodajesz górne i dolne ograniczenie do widoku zawartości komórki, a nie samej komórki. Jeśli dodasz ograniczenie do komórki, kod będzie nadal działał, ale spróbuje użyć wysokości 0.
frin
26

Jeśli używasz ograniczeń autoLayout i UITableViewAutomaticDimension, ten błąd nie jest jakimś błędnym problemem do odrzucenia przez zastąpienie wysokości w kodzie. Oznacza to, że automatyczne określanie wysokości komórki nie działa, ponieważ nie masz wymaganych odpowiednich ograniczeń pionowych.

Jeśli jesteś podobny do mnie i otrzymujesz ten błąd i potrzebujesz pomocy w zidentyfikowaniu, która komórka zgłosiła błąd, możesz dodać następujący wiersz tuż przed zwróceniem metody „heightforRowAtIndexPath”.

NSLog(@"Section %ld Row %ld", (long)[indexPath section], (long)[indexPath row]);

Spowoduje to wydrukowanie długiej listy sekcji i wierszy, ale błąd pojawi się natychmiast po określonej komórce, która powoduje błąd, i możesz szybko zidentyfikować, która komórka powoduje problem i odpowiednio naprawić ograniczenia. Jest to szczególnie przydatne w przypadku komórek statycznych. Zastąpienie wysokości ręcznie wprowadzoną liczbą zadziała, jeśli nie używasz funkcji autoLayout i automatycznych wysokości komórek, ale zasadniczo wyłączy te funkcje, co jest bardzo kiepskim rozwiązaniem, jeśli próbujesz to wykorzystać.

Jeśli wcześniej nie korzystałeś z metody „heightForRowAtIndexPath”, ale chcesz zdebugować ten błąd bez cofania ustawienia UITableViewAutomaticDimension, po prostu dodaj to do swojego kodu:

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    NSLog(@"Section %ld Row %ld", (long)[indexPath section], (long)[indexPath row]);
    return UITableViewAutomaticDimension;
}
user2898617
źródło
Bardzo Ci dziękuję. To mi bardzo pomogło. Na początku pomyślałem, że problem dotyczy innej komórki widoku tabeli. Po debugowaniu okazało się, że problem dotyczy innego.
akozin
Chciałbym to zrobić, ale długi, sekcja i wiersz są niezidentyfikowane. Czy możesz wyjaśnić, co to powinno być w Swift?
DrWhat,
9

Wygląda na to, że w XCode 6.1 występuje błąd, który powoduje ten problem, jeśli używasz automatycznego układu i nie określasz wartości dla wysokości wiersza dla każdej komórki widoku tabeli, ale zamiast tego pozostawiasz wartość „domyślną”. Po prostu zaznaczenie pola wyboru „Niestandardowe” obok wysokości wiersza dla każdej komórki powoduje zniknięcie ostrzeżenia.

ltm
źródło
2
Jeśli używasz samoczynnie zmieniających się rozmiarów komórek, musisz pozostawić wysokość wiersza ustawioną na „domyślną”.
phatmann
1
To rozwiązało ostrzeżenie. Ale wydaje mi się, że pojawia się tylko podczas używania komórek statycznych w TableView
MontiRabbit
1
@phatmann Ten problem pojawia się tylko w przypadku komórek statycznych, dlatego komórki nie powinny zmieniać rozmiaru samodzielnie.
ltm
@ltm może samoczynnie zmieniać rozmiar komórek w statycznych komórkach, jeśli użytkownik może powiększyć tekst? (Wiesz, pod dostępnością w ustawieniach iPhone'a)
Byron Coetsee,
Myślę, że to nie jest błąd, może to być problem z ograniczeniami w pionie, muszą one w pełni opisać wysokość komórki, przynajmniej dla widoków tabel z wymiarami automatycznymi.
juanjo
3

Tak, wszystkie ograniczenia są „szczęśliwe”, nawet w przypadku, gdy masz tylko poziome ograniczenia dla elementów w komórce widoku tabeli. Miałem ten sam problem. Musisz dodać także wiązania pionowe. W ten sposób ostrzeżenie zniknie.

Juraj Antas
źródło
3

Ograniczenia mogą być zadowalające w przypadku układu, ale nie w przypadku automatycznej wysokości wiersza. Szczęśliwy układ oznaczałby, że treść można rozłożyć bez niejasności. To wystarczyłoby do sprawdzenia w Interface Builder.

Szczęśliwy układ dla automatycznej wysokości wiersza oznaczałby, że oprócz powyższego uwzględnisz również ograniczenia na dole komórki.

Więcej tutaj: Wykryto przypadek, w którym ograniczenia niejednoznacznie sugerują wysokość zero

Woodster
źródło
3

Użyłem Wysokość wiersza 43 (lub <> 44) w Inspektorze rozmiaru widoku tabeli i błąd zniknął. Używając 44 otrzymuję błąd. Xcode w wersji 6.0.1.

- Ta odpowiedź została usunięta przez moderatora, proszę tego nie robić, to rozwiązuje problem. To rozwiązuje problem dla mnie i może zrobić to również dla innych. Więc czy mógłbyś być tak uprzejmy, aby nie usuwać go ponownie.

teho
źródło
2

Nie udało mi się usunąć ostrzeżenia, ale aby ograniczenia działały, ustawiłem właściwość tableview new to iOS8 estimatedRowHeightna stałą wysokość i usunąłem heightForRowAtIndexPathimplementację.

Amir
źródło
Jeśli nie usunęło ostrzeżenia, to system nadrabia brakujące ograniczenie i ustawia wysokość wiersza == na właściwość cell.rowHeight. Ostrzeżenie dotyczy właściwości autouzdrawiania, jeśli została naprawiona automatycznie, to znaczy, że problem nie istniał?
Pedro Borges
2

Jeśli otrzymujesz to ostrzeżenie, najprawdopodobniej używasz automatycznego układu, a komórki nie mają żadnych ograniczeń.

Należy zaprzestać używania układu automatycznego lub zaimplementować ograniczenia jednoznacznie definiujące wysokość komórek.

Możesz wyłączyć automatyczny układ w narzędziu do tworzenia interfejsu, odznaczając opcję „Użyj automatycznego układu” w inspektorze plików po prawej stronie.

Jeśli zdecydujesz się na użycie automatycznego układu, a wysokość komórek jest stała, wdrożenie odpowiednich ograniczeń powinno być łatwe. Po prostu dodaj ograniczenia wysokości dla widoków podrzędnych widoku zawartości komórki i zaimplementuj ograniczenia przestrzeni pionowej między widokami podrzędnymi oraz między widokami podrzędnymi a widokiem zawartości. Na przykład, jeśli twoja komórka ma jedną etykietę, zadziała:

Więzy pionowe

  1. Ograniczenie odstępu w pionie między górą widoku zawartości a górą etykiety
  2. Naprawiono ograniczenie wysokości etykiety
  3. Ograniczenie odstępu w pionie między dolną częścią etykiety a dolną częścią widoku zawartości

Więzy poziome

  1. Ograniczenie przestrzeni w poziomie między przednią krawędzią widoku zawartości a przednią krawędzią etykiety
  2. Stałe ograniczenie szerokości etykiety
  3. Ograniczenie odstępu w poziomie między końcową krawędzią etykiety a końcową krawędzią widoku zawartości
wrightak
źródło
Używam ograniczeń i wszyscy wydają się być szczęśliwi, jak wspomniano w pytaniu.
Chris
Czy te ograniczenia dotyczą podglądów podrzędnych widoku zawartości komórki? Jak oni wyglądają? Czy to możliwe, że masz różne komórki? Jeśli definiujesz komórki tak, aby miały stałą wysokość, korzystając z rozwiązań Frederica Bonnera, ograniczenia są nadpisywane.
wrightak
1

W Swift wymuszenie wysokości powrotu rozwiązało mój problem:

override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
    if(indexPath.row == 0){
       return CGFloat(131.0)
    }else if(indexPath.row == 8){
       return CGFloat(97.0)
    }else{
       return CGFloat(44.0)
    }
}
King-Wizard
źródło
1

W przypadku standardowej poprawki bagiennej, bez ograniczeń, bez szacowania wysokości lub nadmiernej inżynierii problemu. Utworzyłem domyślny projekt, podłączyłem widok tabeli, ale zapomniałem umieścić delegata wysokości w kontrolerze widoku . Aby po prostu usunąć to ostrzeżenie, potrzebujesz tego.

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
    return 44;
}

W kontrolerze widoku tabeli.

latenitecoder
źródło
1

Używałem mapView wewnątrz uitableviewcell. Zmieniłem wysokość widoku mapy na 1/3 wielkości ekranu urządzenia. Mam ten sam błąd. Naprawiłem błąd, dodając brakujące ograniczenia do widoku zawartości uitableviewcell.

1) Wyczyść ograniczenia contentView.

2) Ustaw Reset na Sugerowane stałe do contentView.

wprowadź opis obrazu tutaj

3) Dodaj brakujące ograniczenia - jeśli takie istnieją

4) Upewniamy się, że widok treści ma wszystkie wymagane ograniczenia. wprowadź opis obrazu tutaj

AG
źródło
0

W moim przypadku dzieje się tak, ponieważ projektuję komórkę za pomocą xib i zapomniałem dodać ten plik xib do celu.

Po dodaniu tego pliku xib do celu problem zniknął

onmyway133
źródło
0

Chociaż odpowiedzi na tej stronie omawiające dodawanie ograniczeń wysokości lub ręczne zwracanie rowHeights, takich jak 44 in heightForRowAtIndexPath, powodują zniknięcie ostrzeżenia, są one zbędne, ponieważ jest to błąd w Xcode widoczny co najmniej w wersji 6.3.2 (6D2105).

Jeśli ustawisz punkt przerwania w viewDidLoad, zobaczysz self.tableView.rowHeight = -1 (UITableViewAutomaticDimension), nawet jeśli określisz wysokość wiersza 44 w serii ujęć. Dzieje się tak, ponieważ firma Apple błędnie zakłada, że ​​chcesz mieć dynamiczne wysokości wierszy, jeśli pozostawisz wysokość wiersza na 44, ponieważ nie dostarczyły one flagi umożliwiającej określenie preferencji.

Oto kilka możliwych rozwiązań i ich wyniki:

  • Ustaw wysokość wiersza na 43 lub 45 w scenorysie (działa).

  • Ręcznie zwróć wysokość 44 w heightForRowAtIndexPath (działa).

  • Dodaj ograniczenia wysokości między elementami UITableViewCell i jego contentView (działa).

Niestety, te rozwiązania wymagają albo zmiany projektu, dodania niepotrzebnych ograniczeń, albo dodania niepotrzebnego kodu w celu obejścia błędu. Wypróbowałem (tak mi się wydawało) najprostsze rozwiązanie:

  • Ustaw wysokość każdego UITableViewCell na 44 (niestandardowe) w serii ujęć (niepowodzenie).

Naprawdę chciałem uzyskać do tego czysty scenorys, więc w końcu spróbowałem:

  • Dodaj atrybut środowiska uruchomieniowego zdefiniowany przez użytkownika do UITableView w scenorysie i nazwij UITableView z notatką o ustawianiu jego rowHeight, aby przyszli programiści mogli go znaleźć: (działa):

wprowadź opis obrazu tutaj

wprowadź opis obrazu tutaj

Te błędy są zbyt powszechne w programowaniu iOS i zmuszają programistów do spędzania nadmiernego czasu na rozważaniu konsekwencji tego, jak ich rozwiązania wpłyną na łatwość konserwacji w dłuższej perspektywie.

Ponieważ znalezienie konceptualnie poprawnego rozwiązania, które jest możliwe do utrzymania i nie wydaje się zaciemnione, jest tak nieuchwytne, i zakładając, że Apple naprawi błąd i że 44 będzie domyślną wysokością wiersza w dającej się przewidzieć przyszłości, wówczas ograniczenie lub zdefiniowane przez użytkownika rozwiązania atrybutów środowiska wykonawczego są prawdopodobnie najbardziej łatwe w utrzymaniu.

Zack Morris
źródło
0

Myślę, że dzieją się tu dwie ważne rzeczy.

1) Bardzo łatwo jest zrobić błędne ograniczenia, przeciągając ctrl + przeciągając. Więc sprawdź dokładnie, czy wszystko zostało wykonane poprawnie. Aby narysować te ograniczenia, najlepiej użyć tacy po lewej stronie ekranu.

2) Zamiast określania szacowanejRowHeight w ViewDidLoad lub w innym miejscu, użyj metody delegata

override func tableView(tableView: UITableView, estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {}

To od razu rozwiązało problem.

Greg
źródło
Dlaczego używasz nadpisywania?
FractalDoctor
0

Widziałem również ten błąd podczas korzystania z uniwersalnych scenorysów lub xibs. Jeśli zaniedbasz określenie odpowiednich ograniczeń dla klasy rozmiaru Any x Any, zauważyłem, że pojawił się ten błąd.

Wygląda na to, że Apple naprawiło to dla iOS9. U mnie błąd wystąpił dopiero w 8.4.

David Nix
źródło
0

Przez wiele dni chodziłem w kółko między tym błędem a innym błędem, w którym tworzone były ograniczenia (nie mam pojęcia, gdzie), które kolidowały z ograniczeniami, które chciałem. Nawet działało w jednym przypadku, w którym każda widoczna właściwość była identyczna z drugą. Jedynym rozwiązaniem, które znalazłem, było przejście na atomic - utworzenie całkowicie nowego pliku za pomocą xib i ponowne rozpoczęcie ponownego łączenia gniazd, kopiowanie i wklejanie starego kodu. Może to nie jest najlepsze rozwiązanie, ale czasami, jeśli problem nie jest widoczny, pozostaje niewiele więcej do zrobienia. Przynajmniej przejście na atomic to dobry sposób na sprawdzenie, co się dzieje.

Dr Co
źródło