xcode CollectionViewController scrollToItemAtIndexPath not working

前端 未结 9 816
故里飘歌
故里飘歌 2021-02-01 03:06

I have created a CollectionView Control and filled it with images. Now I want to scroll to item at a particular index on start. I have tried out scrollToItemA

相关标签:
9条回答
  • 2021-02-01 03:48

    Also remember that you need to use proper UICollectionviewScrollPosition value. Please see code below for clarification:

    typedef NS_OPTIONS(NSUInteger, UICollectionViewScrollPosition) {
    UICollectionViewScrollPositionNone                 = 0,
    
    /* For a view with vertical scrolling */
    // The vertical positions are mutually exclusive to each other, but are bitwise or-able with the horizontal scroll positions.
    // Combining positions from the same grouping (horizontal or vertical) will result in an NSInvalidArgumentException.
    UICollectionViewScrollPositionTop                  = 1 << 0,
    UICollectionViewScrollPositionCenteredVertically   = 1 << 1,
    UICollectionViewScrollPositionBottom               = 1 << 2,
    
    /* For a view with horizontal scrolling */
    // Likewise, the horizontal positions are mutually exclusive to each other.
    UICollectionViewScrollPositionLeft                 = 1 << 3,
    UICollectionViewScrollPositionCenteredHorizontally = 1 << 4,
    UICollectionViewScrollPositionRight                = 1 << 5
    

    };

    0 讨论(0)
  • 2021-02-01 03:51

    Sometimes collectionView(_:didSelectItemAt:) is either not called on the main thread, or blocks it, causing scrollToItem(at:at:animated:) to not do anything.

    Work around this by doing:

    DispatchQueue.main.async {
      collectionView.scrollToItem(at: indexPath, at: .centeredHorizontally, animated: true)
    }
    
    0 讨论(0)
  • 2021-02-01 03:52

    This is based on @Womble's answer, all credit goes to them:

    The method viewDidLayoutSubviews() gets called repeatedly. For me (iOS 11.2) the first time it gets called the collectionView.contentSize is {0,0}. The second time, the contentSize is correct. Therefore, I had to add a check for this:

    var needsDelayedScrolling = false
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        self.needsDelayedScrolling = true
        // ...
    }
    
    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
        if self.needsDelayedScrolling && collectionView.contentSize.width > 0 {
            self.needsDelayedScrolling = false
            self.collectionView!.scrollToItem(at: someIndexPath,
                    at: .centeredVertically,
                    animated: false)
            }
        }
    }
    

    After adding that extra && collectionView.contentSize.width > 0 it works beautifully.

    0 讨论(0)
提交回复
热议问题