UICollectionView автоматически прокручивается вниз, когда загрузка экрана
Я пытаюсь выяснить, как прокручивать весь путь до нижней части UICollectionView, когда экран загружается первым. Я могу прокручивать нижнюю часть, когда отображается строка состояния, но я хотел бы иметь возможность делать это автоматически при загрузке представления. Нижеследующее работает отлично, если я хочу прокручивать нижнюю часть при касании строки состояния.
- (BOOL)scrollViewShouldScrollToTop:(UITableView *)tableView
{
NSLog(@"Detect status bar is touched.");
[self scrollToBottom];
return NO;
}
-(void)scrollToBottom
{//Scrolls to bottom of scroller
CGPoint bottomOffset = CGPointMake(0, collectionViewReload.contentSize.height - collectionViewReload.bounds.size.height);
[collectionViewReload setContentOffset:bottomOffset animated:NO];
}
Я попытался вызвать [self scrollToBottom] в viewDidLoad. Это не работает. Любые идеи о том, как я могу прокручивать нижнюю часть при загрузке представления?
Ответы
Ответ 1
Просто чтобы уточнить мой комментарий.
viewDidLoad вызывается до того, как элементы визуализируются, поэтому некоторые элементы пользовательского интерфейса нельзя обрабатывать очень хорошо. Такие вещи, как перемещение кнопок вокруг работы, но работа с subviews часто не выполняется (например, прокрутка CollectionView).
Большинство из этих действий будут работать лучше всего, когда вызывается в viewWillAppear или viewDidAppear. Вот за исключением документов Apple, которые указывают на важную вещь, которая стоит делать при переопределении любого из этих методов:
Вы можете переопределить этот метод для выполнения дополнительных задач с представлением представления. Если вы переопределите этот метод, вы должны позвонить супер в какой-то момент вашей реализации.
Супервызов обычно вызывается перед пользовательскими реализациями. (поэтому первая строка кода внутри переопределенных методов).
Ответ 2
Я обнаружил, что ничего не будет работать в viewWillAppear. Я могу заставить его работать только в viewDidLayoutSubviews:
- (void)viewDidLayoutSubviews
{
[super viewDidLayoutSubviews];
[self.collectionView scrollToItemAtIndexPath:[NSIndexPath indexPathForItem:endOfModel inSection:0] atScrollPosition:UICollectionViewScrollPositionNone animated:NO];
}
Ответ 3
Так была аналогичная проблема, и вот еще один способ прийти к ней без использования scrollToItemAtIndexPath
Это будет прокрутка вниз, только если содержимое больше, чем рамка представления.
Вероятно, лучше использовать scrollToItemAtIndexPath, но это еще один способ сделать это.
CGFloat collectionViewContentHeight = myCollectionView.contentSize.height;
CGFloat collectionViewFrameHeightAfterInserts = myCollectionView.frame.size.height - (myCollectionView.contentInset.top + myCollectionView.contentInset.bottom);
if(collectionViewContentHeight > collectionViewFrameHeightAfterInserts) {
[myCollectionView setContentOffset:CGPointMake(0, myCollectionView.contentSize.height - myCollectionView.frame.size.height) animated:NO];
}
Ответ 4
Пример Swift 3
let sectionNumber = 0
self.collectionView?.scrollToItem(at: //scroll collection view to indexpath
NSIndexPath.init(row:(self.collectionView?.numberOfItems(inSection: sectionNumber))!-1, //get last item of self collectionview (number of items -1)
section: sectionNumber) as IndexPath //scroll to bottom of current section
, at: UICollectionViewScrollPosition.bottom, //right, left, top, bottom, centeredHorizontally, centeredVertically
animated: true)
Ответ 5
Получить индексный путь для последнего элемента. Тогда...
- (void)scrollToItemAtIndexPath:(NSIndexPath *)indexPath atScrollPosition:(UICollectionViewScrollPosition)scrollPosition animated:(BOOL)animated
Ответ 6
Для меня я нашел следующее решение:
вызовите reloadData в CollectionView и сделайте dcg on main для прокрутки.
__weak typeof(self) wSelf = self;
[wSelf.cv reloadData];
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"HeightGCD:%@", @(wSelf.cv.contentSize.height));
[wSelf.cv scrollToItemAtIndexPath:[NSIndexPath indexPathForItem:50 inSection:0] atScrollPosition:UICollectionViewScrollPositionBottom animated:YES];
});
Ответ 7
Вероятно, проблема заключается в том, что даже если ваше представление коллекции находится на экране, оно может не иметь фактического contentSize
.
Если вы прокрутите viewDidAppear
, у вас будет contentSize
, но ваш scollectionview кратко покажет содержимое перед прокруткой.
И проблема с viewDidLayoutSubviews
состоит в том, что он вызывается несколько раз, поэтому вам нужно добавить некрасивое логическое значение, чтобы ограничить прокрутку.
Лучшее решение, которое я нашел, - заставить отображаться макет.
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
// force layout before scrolling to most recent
collectionView.layoutIfNeeded()
// now you can scroll however you want
// e.g. scroll to the right
let offset = collectionView.contentSize.width - collectionView.bounds.size.width
collectionView.setContentOffSet(CGPoint(x: offset, y: 0), animated: animated)
}