UICollectionView: set new layout and offset target content

I have a UICollectionView and two subclasses of UICollectionViewFlowLayout . When a cell is selected, I call setCollectionViewLayout:animated: to switch between layouts. After the transition is complete, the selected cell is centered, which is excellent.

Is it possible to perform the same centering behavior without actually selecting a cell? I tried calling setContentOffset:animated: many ways without any success. Alternatively, can I specify a self- contentOffset for the displayed layout?

To be more clear, I would like to have something like this without changing the selected cell property: enter image description here

EDIT # 1

This is what I already have:

 [self.collectionView selectItemAtIndexPath:indexPath animated:NO scrollPosition:UICollectionViewScrollPositionNone]; [self.collectionView setCollectionViewLayout:layout animated:YES]; 

It looks great: https://www.dropbox.com/s/9u6cnwwdbe9vss0/17249646-0.mov


But if I skip selectItemAtIndexPath :

 [self.collectionView setCollectionViewLayout:layout animated:YES]; [self.collectionView scrollRectToVisible:targetFrame animated:YES]; 

This is not so beautiful (wave animation): https://www.dropbox.com/s/s3u2eqq16tmex1v/17249646-1.mov

+4
source share
1 answer

EDIT (modified response after further clarification)

I did with table views here . Basically, you call scrollRectToVisible:animated: rectangle that will position your scroll view where you want it to end. For accurate positioning, I think you just need to calculate a rectangle of the same size as your view. Please note: if the content size will change, the rectangle should be calculated in the expected final size of the content.

ORIGINAL RESPONSE

You can change the layout generated by the layoutAttributesForElementsInRect:rect overriding layoutAttributesForElementsInRect:rect like this:

 - (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect { NSArray *poses = [super layoutAttributesForElementsInRect:rect]; if (<test whether we want to modify poses>) { UICollectionViewLayoutAttributes *pose = poses[<index of pose to be modified>]; pose.frame = <some other frame>;//modify the frame, for example } return poses; } 

You also need to override layoutAttributesForItemAtIndexPath using similar logic. The next step will be to invalidate or replace the layout when you want changes to occur. You also need to pass some information. The layout must know what to do so that you can pass it the appropriate data or extend UICollectionViewDelegateFlowLayout1 .

0
source

Source: https://habr.com/ru/post/1487606/


All Articles