2014-10-14 4 views
1

я искал ответ на другие вопросы, StackOverflow, но я не мог найти решение следующей проблеме:Держите первый видимый элемент в UICollectionView после поворота

Я пытаюсь использовать UICollectionView с компоновкой потока (по вертикали) и размер элемента зависит от размера экрана (он должен использовать ширину iPad или даже ширину iPhone в альбомной ориентации).

Я хочу сделать дисплей UICollectionView только одним столбцом элементов на портфолио, ориентированном на iPhone, но 2 на ландшафтно ориентированном iPhone. И, конечно, сделайте его общим, чтобы он мог отображать больше столбцов, если доступно более горизонтальное помещение, например, в iPad.

Для достижения такого поведения, я сделал следующее:

- (void)viewWillLayoutSubviews { 

    [super viewWillLayoutSubviews]; 

    UICollectionViewFlowLayout *layout = (UICollectionViewFlowLayout *)self.collectionView.collectionViewLayout; 
    NSInteger columns = 1 + ((NSInteger)(CGRectGetWidth(self.collectionView.frame) - layout.sectionInset.left - layout.sectionInset.right + layout.minimumInteritemSpacing))/((NSInteger)(layout.minimumInteritemSpacing + 300.0 + 1.0)); 
    layout.itemSize = CGSizeMake((CGRectGetWidth(self.collectionView.frame) - layout.sectionInset.left - layout.sectionInset.right - ((columns - 1) * layout.minimumInteritemSpacing))/columns, layout.itemSize.height); 

    [layout invalidateLayout]; 
} 

Это работает довольно хорошо, и когда я поворачиваю мой телефон, я могу увидеть макет отображения двух столбцов вместо одного.

Но я не могу заставить UICollectionView сохранить первый видимый элемент после вращения, поскольку он устанавливает смещение содержимого до того, что было до поворота. Когда макет изменился, и теперь UICollectionView отображает два столбца в альбомной ориентации, это новое смещение содержимого должно иметь новое значение, соответствующее одному и тому же элементу, но под новым макетом.

Я попытался использовать следующий фрагмент, но я не смог заставить его работать:

- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration { 

    NSIndexPath *firstAddShowCellIndexPath = [[[self.collectionView indexPathsForVisibleItems] sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) { 
     NSIndexPath *ip1 = obj1; 
     NSIndexPath *ip2 = obj2; 
     return [ip1 compare:ip2]; 
    }] firstObject]; 

    if (firstAddShowCellIndexPath) { 
     [self.collectionView scrollToItemAtIndexPath:firstAddShowCellIndexPath atScrollPosition:UICollectionViewScrollPositionTop animated:YES]; 
    } 
} 

Я подозреваю, что UICollectionView пытается управлять содержимым смещения во время вращения, так что я даже попытался с помощью dispatch_after или willRotateToInterfaceOrientation, но хотя он и сработал, он установил смещение контента до конца, после того, как ротация закончилась, что дало действительно плохую работу пользователя.

Любые идеи?

Спасибо всем!

ответ

0

Это работает для меня,

Добавить это вместо willRotation метода

#pragma mark - Rotation 
-(void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator 
{ 
    [self.collectionView.collectionViewLayout invalidateLayout]; 
} 

Подобно тому, как пример, это мой быстрый код для создания две колонки до и после поворота, и т.д.

#pragma mark <UICollectionViewDelegateFlowLayout> 
- (CGSize)collectionView:(UICollectionView *)collectionView layout(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath*)indexPath 
{ 
    int width = roundf(self.collectionView.frame.size.width/2.0) - 15; 
    int height = roundf(width * 0.8); 
    return CGSizeMake(width, height); 
} 

- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section 
{ 
    UIEdgeInsets new = UIEdgeInsetsMake(10, 10, 10, 10); 
    return new; 
} 
Смежные вопросы