layoutIfNeeded
zmusza odbiornik do natychmiastowego układu swoich widoków w razie potrzeby.
Załóżmy, że nadpisałeś layoutSubviews
, a UIKit uważa, że Twój widok wymaga układu z dowolnego powodu (np. Zadzwoniłeś pod numer setNeedsLayout
podczas obsługi niektórych działań użytkownika). Wtedy twoja niestandardowa metoda layoutSubviews
będzie wywoływana natychmiast, zamiast wtedy, gdy normalnie będzie wywoływana w zwykłej sekwencji zdarzeń pętli UIKit (po obsłudze zdarzeń, ale przed drawRect:
).
Przykładem dlaczego może trzeba zadzwonić layoutIfNeeded
obrębie jednej pętli biegu:
- zmienić rozmiar widoku niestandardowego zawierający widok tabeli z niestandardowego układu.
setNeedsLayout
jest ustawiony tak, że layoutSubviews
zostanie wywołany później.
- Obiekt kontrolera prosi o widok tabeli, aby przewinąć do określonej komórki podczas obsługi zdarzenia użytkownika.
- Twój niestandardowy widok wykonuje niestandardowy rozmiar widoku tabeli w
layoutSubviews
, który zmienia rozmiar widoku tabeli.
Problem polegał na tym, że kontroler poprosił o widok tabeli, aby przewinąć (krok 2), widok tabeli miał nieaktualne granice. Zaktualizowane granice zostaną ustawione później w widoku tabeli (krok 3). To, czego kontroler chciał, aby widok tabeli mógł przewinąć, może nie być widoczny po wykonaniu layoutSubviews
. Rozwiązaniem byłoby wówczas, gdyby kontroler zadzwonił pod numer layoutIfNeeded
w sytuacjach, gdy wie, że może to nastąpić.
To nie jest prawda. setNeedsLayout będzie oznaczać widok dla układu, co spowoduje wywołanie layoutSubviews w innym cyklu runloop. Wywołanie layoutIfNeeded spowoduje wywołanie layoutSubviews w tym samym cyklu runloop. Aby przetestować, ustaw punkt przerwania w layoutSubviews, a następnie punkt przerwania w wywołaniu setNeedsLayout. Jeśli przejdziesz do jednej linii, zauważysz, że nie włamujesz się do layoutSubviews. Jednakże, jeśli złamiesz layoutIfNeeded i prześlesz linię, zauważysz, że ZROBISZ rozkładekSubviews przed awansem. – tyler
dang, co za poważny głos –