Запустите UICollectionView по определенному пути индекса
В настоящее время у меня есть представление коллекции, которое выполняет горизонтальный пейджинг, где каждая ячейка является полноэкранным. То, что я хочу сделать, - это просмотр коллекции, который начинается с определенного индекса, когда он показывает.
Сейчас я использую scrollToItemAtIndexPath: atScrollPosition: анимированный: с анимированным набором в НЕТ, но он все еще загружает первый индекс, прежде чем он сможет перейти к определенному элементу. Также кажется, что я могу использовать этот метод только в ViewDidAppear, поэтому он показывает первую ячейку и затем мигает в ячейке, которую я хочу показать. Я скрываю это, скрывая представление коллекции до тех пор, пока свиток не закончится, но он не кажется идеальным.
Есть ли лучший способ сделать это иначе, чем то, как я это описал?
Спасибо!
Ответы
Ответ 1
Поэтому я решил это другим способом, используя метод UICollectionViewDelegate
и одноразовый Bool
:
Swift 2:
var onceOnly = false
internal func collectionView(collectionView: UICollectionView, willDisplayCell cell: UICollectionViewCell, forItemAtIndexPath indexPath: NSIndexPath) {
if !onceOnly {
let indexToScrollTo = NSIndexPath(forRow: row, inSection: section)
self.problemListCollectionView.scrollToItemAtIndexPath(indexToScrollTo, atScrollPosition: .Left, animated: false)
onceOnly = true
}
}
Swift 3:
var onceOnly = false
internal func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
if !onceOnly {
let indexToScrollTo = IndexPath(item: row, section: section)
self.problemListCollectionView.scrollToItem(at: indexToScrollTo, at: .left, animated: false)
onceOnly = true
}
}
Этот код выполняется до того, как произойдет какая-либо анимация (поэтому он действительно загружается до этой точки), что лучше, чем пытаться вызвать viewDidAppear
, и я не имел успеха с ним в viewWillAppear
.
Ответ 2
Чтобы решить эту проблему, я частично использовал ответ оранжерея.
/// Edit
var startIndex: Int! = 0
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
collectionView.setNeedsLayout()
collectionView.layoutIfNeeded()
collectionView.scrollToItemAtIndexPath(
NSIndexPath(forItem: 0, inSection: startIndex),
atScrollPosition: .None,
animated: false)
}
Проблема, кажется, в неправильном размере collectionView
. После установки макета scrollToItemAtIndexPath
вы получите необходимый результат.
Также кажется, что эта проблема сохраняется только тогда, когда a Collection View
используется внутри UIViewController
.
Ответ 3
это показалось мне полезным:
- (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];
}
Ответ 4
Swift 3.0 протестирован и работает.
var onceOnly = false
internal func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
if !onceOnly {
//set the row and section you need.
let indexToScrollTo = IndexPath(row: 1, section: indexPath.section)
self.fotmCollectionView.scrollToItem(at: indexToScrollTo, at: .left, animated: false)
onceOnly = true
}
}
Ответ 5
Передайте indexPath из первого VC в представление коллекции в методе DidSelectItemAtIndexPath. В viewDidLoad вашего представления коллекции используйте метод scrollToItemAtIndexPath:atScrollPosition:animated:
Установить animated
на NO
и atScrollPosition
на UICollectionViewScrollPositionNone
. Вот так:
[self.collectionView scrollToItemAtIndexPath:self.indexPathFromVC atScrollPosition:UICollectionViewScrollPositionNone animated:NO];
Ответ 6
Вот что сработало для меня (в классе UICollectionViewController):
private var didLayoutFlag: Bool = false
public override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
if let collectionView = self.collectionView {
if !self.didLayoutFlag {
collectionView.scrollToItemAtIndexPath(self.viewModel.initialIndexPath, atScrollPosition: .None, animated: false)
self.didLayoutFlag = true
}
}
}
Ответ 7
Эй, я решил с задачей c.
Я думаю, это полезно для вас.
Вы также можете преобразовать Objective c в swift.
Вот мой код:
** В моем случае нажмите кнопку "Вкл", чтобы активировать конкретный индекс, который равен 3 **
для вертикальной
- (IBAction)Click:(id *)sender {
NSInteger index=3;
CGFloat pageHeight = self.collectionView.frame.size.height;
CGPoint scrollTo = CGPointMake(0, pageHeight * index);
[self.collectionView setContentOffset:scrollTo animated:YES];
}
Для горизонтальной
- (IBAction)Click:(id *)sender {
NSInteger index=3;
CGFloat pageWidth = self.collectionView.frame.size.width;
CGPoint scrollTo = CGPointMake(pageWidth * index, 0);
[self.collectionView setContentOffset:scrollTo animated:YES];
}
Я надеюсь, что это может помочь вам.
Ответ 8
Я пришел сюда с этой же проблемой и обнаружил, что в моем случае эта проблема была вызвана тем, что ViewController в моей раскадровке был установлен как размер свободной формы.
Я предполагаю, что viewWillLayoutSubviews вызывается для вычисления правильного размера, когда представление сначала загружается, если размеры раскадровки оставляют это непонятным. (Я определил свой viewController в своем раскадровке как "свободную форму", поэтому я мог бы сделать его очень высоким, чтобы видеть/редактировать многие ячейки в длинном tableView внутри моего CollectionView).
Я обнаружил, что victor.vasilica и парниковый подход повторяют: ввод команды "scrollToRow" в viewWillLayoutSubviews отлично работает, чтобы исправить проблему.
Однако я также обнаружил, что, как только я снова сделал VC в своем фиксированном размере, проблема сразу же исчезла, и я смог установить начальную ячейку из viewWillAppear. Ваша ситуация может быть иной, но это помогло мне понять, что происходит в моей ситуации, и я надеюсь, что мой ответ может помочь другим людям сообщить эту проблему.