UICollectionView автоматическая прокрутка до ячейки в IndexPath



перед загрузкой представления коллекции пользователь задает номер изображения в массиве представления коллекции. Все ячейки не помещаются на экране. У меня 30 клеток и только 6 на экране.



вопрос: как прокрутить до ячейки с нужным изображением автоматически при загрузке UICollectionView?

647   8  

8 ответов:

Новый, Отредактированный Ответ:

добавить в viewDidLayoutSubviews

Свифт

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    let indexPath = IndexPath(item: 12, section: 0)
    self.collectionView.scrollToItem(at: indexPath, at: [.centeredVertically, .centeredHorizontally], animated: true)
}

как правило, .centerVertically в случае

ObjC

-(void)viewDidLayoutSubviews {
   [super viewDidLayoutSubviews];
    NSIndexPath *indexPath = [NSIndexPath indexPathForItem:12 inSection:0];
   [self.collectionView scrollToItemAtIndexPath:indexPath atScrollPosition:UICollectionViewScrollPositionCenteredVertically | UICollectionViewScrollPositionCenteredHorizontally animated:NO];
}

старый ответ работает для старых iOS

добавить в viewWillAppear:

[self.view layoutIfNeeded];
[self.collectionView scrollToItemAtIndexPath:indexPath atScrollPosition:UICollectionViewScrollPositionCenteredVertically animated:NO];

Я обнаружил, что прокрутка в viewWillAppear может не работать надежно, потому что представление коллекции еще не закончило свой макет; вы можете прокрутить до неправильного элемента.

Я также обнаружил, что прокрутка в viewDidAppear вызовет мгновенную вспышку развернутого представления, чтобы быть видимым.

и, если вы прокручиваете каждый раз через viewDidLayoutSubviews, пользователь не сможет вручную прокручивать, потому что некоторые макеты коллекций вызывают макет подвида каждый раз, когда вы свиток.

вот что я нашел надежно работает:

- (void)viewDidLayoutSubviews {
    [super viewDidLayoutSubviews];

    // If we haven't done the initial scroll, do it once.
    if (!self.initialScrollDone) {
        self.initialScrollDone = YES;

        [self.collectionView scrollToItemAtIndexPath:self.myInitialIndexPath
                                    atScrollPosition:UICollectionViewScrollPositionRight animated:NO];
    }
}

Я полностью согласен с вышеуказанным ответом. Единственное, что для меня решение было установлено код в viewDidAppear

viewDidAppear 
{
    [self.collectionView scrollToItemAtIndexPath:indexPath atScrollPosition:UICollectionViewScrollPositionCenteredVertically animated:YES];
}

когда я использовал viewWillAppear прокрутка не работает.

это, казалось, работает для меня, его похож на другой ответ, но имеет некоторые отличия:

- (void)viewDidLayoutSubviews
{     
   [self.collectionView layoutIfNeeded];
   NSArray *visibleItems = [self.collectionView indexPathsForVisibleItems];
   NSIndexPath *currentItem = [visibleItems objectAtIndex:0];
   NSIndexPath *nextItem = [NSIndexPath indexPathForItem:someInt inSection:currentItem.section];

   [self.collectionView scrollToItemAtIndexPath:nextItem atScrollPosition:UICollectionViewScrollPositionNone animated:YES];
}

Swift:

your_CollectionView.scrollToItemAtIndexPath(indexPath, atScrollPosition: UICollectionViewScrollPosition.CenteredHorizontally, animated: true)

Swift 3

let indexPath = IndexPath(row: itemIndex, section: sectionIndex)

collectionView.scrollToItem(at: indexPath, at: UICollectionViewScrollPosition.right, animated: true)

Свиток Позиции:

UICollectionViewScrollPosition.CenteredHorizontally / UICollectionViewScrollPosition.CenteredVertically

вы можете использовать GCD для отправки прокрутки в следующую итерацию основного цикла запуска в viewDidLoad для достижения этого поведения. Прокрутка будет выполнена до того, как на экране появится представление коллекции, поэтому мигать не будет.

- (void)viewDidLoad {
    dispatch_async (dispatch_get_main_queue (), ^{
        NSIndexPath *indexPath = YOUR_DESIRED_INDEXPATH;
        [self.collectionView scrollToItemAtIndexPath:indexPath atScrollPosition:UICollectionViewScrollPositionCenteredHorizontally animated:NO];
    });
}

Я бы рекомендовал сделать это в collectionView: willDisplay: тогда вы можете быть уверены, что делегат представления коллекции доставляет что-то. Вот мой пример:

func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
    /// this is done to set the index on start to 1 to have at index 0 the last image to have a infinity loop
    if !didScrollToSecondIndex {
        self.scrollToItem(at: IndexPath(row: 1, section: 0), at: .left, animated: false)
        didScrollToSecondIndex = true
    }
}

все ответы здесь - хаки. Я нашел лучший способ прокрутить представление коллекции где-то после relaodData:
Подкласс коллекции вид макета что когда-либо макет вы используете, переопределить метод prepareLayout, после супер вызова установить, что когда-либо смещение вам нужно.
пример: https://stackoverflow.com/a/34192787/1400119

Comments

    Ничего не найдено.