33

画面が最初に読み込まれたときに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];
 }

viewDidLoadで[selfscrollToBottom]を呼び出してみました。これは機能していません。ビューが読み込まれたときに一番下までスクロールする方法について何かアイデアはありますか?

4

9 に答える 9

37

viewWillAppearでは何も機能しないことがわかりました。viewDidLayoutSubviewsでのみ動作させることができます:

- (void)viewDidLayoutSubviews
{
    [super viewDidLayoutSubviews];

    [self.collectionView scrollToItemAtIndexPath:[NSIndexPath indexPathForItem:endOfModel inSection:0] atScrollPosition:UICollectionViewScrollPositionNone animated:NO];
}
于 2014-08-16T00:21:07.270 に答える
19

私のコメントを詳しく説明します。

viewDidLoadは要素が視覚化される前に呼び出されるため、特定のUI要素を適切に操作することはできません。ボタンを動かしたり、サブビューを処理したりすることはできません(CollectionViewのスクロールなど)。

これらのアクションのほとんどは、viewWillAppearまたはviewDidAppearで呼び出されたときに最適に機能します。これらの方法のいずれかをオーバーライドするときに行うべき重要なことを指摘しているAppleドキュメントからの例外は次のとおりです。

このメソッドをオーバーライドして、ビューの表示に関連する追加のタスクを実行できます。このメソッドをオーバーライドする場合は、実装のある時点でsuperを呼び出す必要があります。

スーパーコールは通常、カスタム実装の前に呼び出されます。(したがって、オーバーライドされたメソッド内のコードの最初の行)。

于 2013-02-08T00:43:18.793 に答える
11

同様の問題がありました。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];
}
于 2015-10-21T21:06:59.907 に答える
6

Swift3の例

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)
于 2016-11-11T18:05:59.040 に答える
4

最後のアイテムのインデックスパスを取得します。それで...

- (void)scrollToItemAtIndexPath:(NSIndexPath *)indexPath atScrollPosition:(UICollectionViewScrollPosition)scrollPosition animated:(BOOL)animated
于 2013-06-01T15:39:33.163 に答える
3

私にとって、私は次の解決策を見つけました:

CollectionViewでreloadDataを呼び出し、mainでdcgを作成してスクロールします。

 __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];
 });
于 2015-10-23T09:56:26.357 に答える
2

この問題は、コレクションビューが画面に表示されていても、実際のが表示されていない可能性があります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)
}
于 2019-10-17T13:42:28.260 に答える
2

これらのどれも私にとってそれほどうまく機能していませんでした、私はこれで終わりましたこれはどんなスクロールビューでも機能します

extension UIScrollView {
    func scrollToBottom(animated: Bool) {
        let y = contentSize.height - 1
        let rect = CGRect(x: 0, y: y + safeAreaInsets.bottom, width: 1, height: 1)
        scrollRectToVisible(rect, animated: animated)
    }
}
于 2021-01-14T22:24:23.287 に答える
0

performBatchUpdates次のように使用できるかどうかを検討してください。

private func reloadAndScrollToItem(at index: Int, animated: Bool) {
    collectionView.reloadData()
    collectionView.performBatchUpdates({
        self.collectionView.scrollToItem(at: IndexPath(item: index, section: 0),
                                         at: .bottom,
                                         animated: animated)
    }, completion: nil)
}

がコレクションのビューデータソースの最後のアイテムのインデックスである場合index、一番下までスクロールします。

于 2020-10-30T12:00:45.547 に答える