iOS 7: Keeping the displayed items in the viewing

2020-04-19 05:38发布

问题:

I'm using a UICollectionView with horizontal scrolling (Layout = UICollectionViewFlowLayout). After rotation I adapt the content offset so that the same items are displayed before the rotation. On rotation the width of the items are changed, because there are always seven items on screen. My current approach does work for iOS 8, but not for iOS 7.

On iOS 7 layoutAttributesForItemAtIndexPath always returns the same X position regardless of the orientation. So it seems that some frame is not correctly adapted. The calculation of the size of the items seems to be correct, because they changes accordingly.

This is my code:

My main view controller:

public override void DidRotate (UIInterfaceOrientation fromInterfaceOrientation)
{
    base.DidRotate (fromInterfaceOrientation);
    myProblematicCollectionView.invalidateLayout ();
}

The method from the collection view:

public void invalidateLayout(){
    Layout.InvalidateLayout ();
    UICollectionViewLayoutAttributes layoutAttributesForItem = CollectionView.GetLayoutAttributesForItem (NSIndexPath.FromItemSection (0, CurrentVisibleSection));
    CollectionView.SetContentOffset (new CGPoint (layoutAttributesForItem.Frame.X, 0), false);      
}

The code is in C# but it shouldn't bother you. You can of corse post solutions in Objective-C or Swift.

CurrentVisibleSection is the section with the seven items. It is always up-to-date. When GetLayoutAttributesForItem or layoutAttributesForItemAtIndexPath is called, the GetSizeForItem or collectionView:layout:sizeForItemAtIndexPath: is called before the content offset is set.

Has anyone a clue why I always get the same layout attribute regardless of the orientation?

Edit:

If I use reloadData before calling layoutAttributesForItemAtIndexPath I get the correct size. Do I need this after invalidateLayout?

What I also don't get is that the collection view has the correct size (frame width is correct).