简体   繁体   中英

UICollectionView set default position


I have a CollectionView with 3 Cells which extend across the whole device's screen and basically represent my 3 main views.
I have paging enabled, so it basically works exactly like the iOS home screen right now.
My problem is that I want the "default" position of this CollectionView to be equal to view.frame.width so that the second Cell is the "default" view and I can swipe left and right to get to my secondary views.
I have already tried via

collectionView.scrollToItem()

and

collectionView.scrollRectToVisible()

as well as

collectionView.setContentOffset()

but they all seem to work only after the view has loaded (I tried them via a button in my navigation bar). Thank you in advance!


EDIT:
Now this works, but I also have another collection view in that one middle cell which holds a list of little 2-paged UICollectionView s which are actually objects from a subclass of UICollectionViewCell called PersonCell each holding a UICollectionView . I want these UICollectionViews to be scrolled to index 1 as well, this is my code:

for tabcell in (collectionView?.visibleCells)! {
    if let maincell: MainCell = tabcell as? MainCell {
        for cell in maincell.collectionView.visibleCells {
            if let c = cell as? PersonCell {
                c.collectionView.scrollToItem(at: (NSIndexPath(item: 1, section: 0) as IndexPath), at: [], animated: false)
            }
        }
    }
}

This is executed in the viewDidLayoutSubviews of my 'root' CollectionViewController .



EDIT 2: Now I tried using following code in the MainCell class (it's a UICollectionViewCell subclass):

func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
    let personCell = cell as! PersonCell
    personCell.collectionView.scrollToItem(at: (NSIndexPath(item: 1, section: 0) as IndexPath), at: [], animated: false)
}



EDIT 3:
Long story short, I basically need a delegate method that is called after a cell has been added to the UICollectionView .

Did you try [self.collectionView scrollToItemAtIndexPath:indexPath atScrollPosition:UICollectionViewScrollPositionCenteredHorizontally animated:YES];

Try calling the code in viewDidLayoutSubviews

Okay, I got it!
This SO answer gave me the final hint:
https://stackoverflow.com/a/16071589/3338129
Basically, now I just do this after initialization of the Cell:

self.collectionView.alpha = 1
self.data = data // array is filled with data
self.collectionView.reloadData()
DispatchQueue.main.async {
    for cell in self.collectionView.visibleCells {
        (cell as! PersonCell).collectionView.scrollToItem(at: (NSIndexPath(item: 1, section: 0) as IndexPath), at: [], animated: false)
    }
    self.collectionView.alpha = 1
}

Basically, the code in the DispatchQueue.main.async{...} is called on the next UI refresh cycle which means at a point where the cells are already there. To prevent the user from seeing the wrong page for a fraction of a second, I set the whole collectionView's alpha to 0 and toggle it on as soon as the data is there, the cell is there and the page has scrolled.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM