2015-03-13 4 views
16

настоящее время у меня следующий фрагмент кода для вычисления UICollectionViewCells размеров:UICollectionView Invalidate Компоновка на изменение границ

- (CGSize)collectionView:(UICollectionView *)mainCollectionView 
        layout:(UICollectionViewLayout *)collectionViewLayout 
    sizeForItemAtIndexPath:(NSIndexPath *)atIndexPath 
{ 
    CGSize bounds = mainCollectionView.bounds.size; 
    bounds.height /= 4; 
    bounds.width /= 4; 
    return bounds; 
} 

Это работает. Тем не менее, теперь я добавляю наблюдателя клавиатуры в viewDidLoad (который запускает методы делегата и источника данных для UICollectionView перед тем, как он появится и изменит размеры из раскадровки). Следовательно, границы являются неправильными. Я также хотел бы поддержать ротацию. Каков хороший способ обработки этих двух краевых случаев и пересчет размеров, если размер UICollectionView изменит размер?

ответ

38

Решение недействительности макет, когда границы изменения зрения коллекционных переопределить shouldInvalidateLayoutForBoundsChange: и вернуть YES. Это также указано в документации: https://developer.apple.com/documentation/uikit/uicollectionviewlayout/1617781-shouldinvalidatelayoutforboundsc

- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds 
{ 
    return YES; 
} 

Это должно охватывать поддержку вращения, а также. Если этого не произойдет, реализовать viewWillTransitionToSize:withTransitionCoordinator:

- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator 
{ 
    [super viewWillTransitionToSize:size 
      withTransitionCoordinator:coordinator]; 

    [coordinator animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext> context) 
    { 
     [self.collectionView.collectionViewLayout invalidateLayout]; 
    } 
           completion:^(id<UIViewControllerTransitionCoordinatorContext> context) 
    { 
    }]; 
} 
+1

Анимация рядом с переходом .... это великолепно. Спасибо! – 3rdFunkyBot

7
  1. Вы должны обработать случай, когда размер вида коллекций изменен. Если вы измените ориентацию или ограничения, будет запущен метод viewWillLayoutSubviews.

  2. Вы должны аннулировать текущий макет представления коллекций. После того как макет недействителен с помощью метода invalidateLayout, будут запущены методы UICollectionViewDelegateFlowLayout.

Вот пример кода:

 
- (void)viewWillLayoutSubviews { 
    [super viewWillLayoutSubviews]; 
    [mainCollectionView.collectionViewLayout invalidateLayout]; 
} 
+9

, когда я пытался, что мое приложение висит из-за метода '-viewWillLayoutSubviews' быть вызван бесконечно .. сделал я поставить этот код в неправильный контроллер? Также я могу вызвать супер? – igrek

+0

Это также хорошо, когда вам нужно иметь настраиваемые макеты в контроллерах A, B и C на панели табуляции, так что, когда вы находитесь на VC A и вращаетесь, вам нужно, чтобы VC B обновил его макет, чтобы, если пользователь переходы на VC B, вы по-прежнему показываете правильно повернутое представление. – JohnZ