Wdrażam widok kolekcji, którego elementy mają rozmiar oparty na granicach widoku kolekcji. Dlatego też, gdy zmienia się rozmiar, na przykład z powodu obracania urządzenia, muszę unieważnić układ, aby zmienić rozmiar komórek, aby uwzględnić nowe ograniczenia widoku kolekcji. Zrobiłem to za pośrednictwem interfejsu API viewWillTransitionToSize
.Prawidłowy sposób unieważnienia układu widoku kolekcji po zmianie rozmiaru
Działa to dobrze, dopóki użytkownik nie przedstawi kontrolera widoku modalnego nad kontrolerem widoku, który zawiera widok kolekcji, obraca urządzenie, a następnie je odrzuca. W takim przypadku rozmiar elementu nie został zaktualizowany do odpowiedniego rozmiaru. viewWillTransitionToSize
jest wywoływane, a układ jest unieważniany zgodnie z oczekiwaniami, ale ograniczenia widoku kolekcji nadal są starymi wartościami. Na przykład podczas obracania z pionowej na poziomą wartość graniczna widoku kolekcji nadal ma wysokość większą niż szerokość. Nie jestem pewien, dlaczego tak jest, ale zastanawiam się, czy to najlepszy sposób na unieważnienie zmiany rozmiaru? Czy istnieje lepszy sposób na zrobienie tego?
Próbowałem również podklasy UICollectionViewFlowLayout
i przesłonięcie shouldInvalidateLayoutForBoundsChange
, aby zwrócić YES
, ale z jakiegoś powodu to nie działa nawet obracanie bez prezentacji modalnej. Nie używa też właściwych granic widoku kolekcji.
- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(nonnull id<UIViewControllerTransitionCoordinator>)coordinator
{
[super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
[self.collectionView.collectionViewLayout invalidateLayout];
[coordinator animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext> __nonnull context) {
[self.collectionView.collectionViewLayout invalidateLayout];
} completion:^(id<UIViewControllerTransitionCoordinatorContext> __nonnull context) {
//finished
}];
}
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewFlowLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath
{
//collectionView.bounds.size is not always correct here after invalidating layout as explained above
}
Próbowałem również jego invaliding w bloku zakończenia, ale nadal nie używa prawidłowych granic widoku kolekcji.
Jeśli ponownie unieważnię układ w viewWillAppear
, to używa on prawidłowych granic widoku kolekcji, co rozwiązuje problem z obracaniem się z modalnie przedstawionym kontrolerem widoku. Ale to nie powinno być konieczne, być może istnieją inne sytuacje, w których nie zostanie to odpowiednio dobrane.
Czy obejrzałeś http://stackoverflow.com/questions/29023473/uicollectionview-invalidate-layout-on-bounds-changes? – ozgur
@ozgur Już wypróbowałem, co jest w tej odpowiedzi tak, jak wyjaśniono powyżej – Joey
Czy jesteś pewien, że nie aktualizujesz niczego w 'viewWillAppear()'? W opisanym scenariuszu (zmieniasz orientację, gdy kontroler modalny jest zakończony), gdy kontroler widoku modalnego jest odrzucany, możesz otrzymać ramkę z * poprzednim * orientacją w 'viewWillAppear()', i poprawną ramkę w 'viewDidAppear() '. Więc to, co zwykle działa dla mnie, to tylko aktualizacja układu w 'viewWillTransitionToSize'. –