Background
I am implementing a UICollectionView
(for the first time) in an effort to achieve a paged horizontal scroll view of tiles. I'd like each tile to show in the center of the frame with it's sister tiles partially visible to the left and right (something like the page selector in the Safari app). I'm interested in using the UICollectionView
to take advantage of built-in cell dequeueing and would rather not use a rotated UITableView
.
Issue
The issue I'm finding is that when using pagingEnabled = YES
and clipsToBounds = NO
, the UICollectionView
removes cells outside the collectionView
frame (they're not in the visibleCells
array) as soon as paging is complete. Can anyone provide advice on how to achieve the effect of displaying previews of the sister tiles while maintaining this basic setup? Or am I approaching this incorrectly?
Screenshots
start scrolling end
The scrolling screen is exactly correct. But in the start and end shots I want there to be green visible in the blue margins.
Here's what's in my AppDelegate.m (credit to tutsplus.com for the basic setup here):
#import "AppDelegate.h"
@interface ViewController : UICollectionViewController
@end
@implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
[self.collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:@"ID"];
[self.view setBackgroundColor:[UIColor blueColor]];
// pad the collection view by 20 px
UIEdgeInsets padding = UIEdgeInsetsMake(20.0, 20.0, 20.0, 20.0);
[self.collectionView setFrame:UIEdgeInsetsInsetRect(self.view.frame, padding)];
// set pagingEnabled and clipsToBounds off
[self.collectionView setPagingEnabled:YES];
[self.collectionView setClipsToBounds:NO];
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
return 5;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"ID" forIndexPath:indexPath];
UILabel *label = [[UILabel alloc] initWithFrame:cell.bounds];
label.textAlignment = NSTextAlignmentCenter;
label.text = [NSString stringWithFormat:@"%d", indexPath.row];
[label setBackgroundColor:[UIColor greenColor]];
[cell.contentView addSubview:label];
return cell;
}
@end
@implementation AppDelegate
{
ViewController *vc;
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// setup the UICollectionViewFlowLayout
UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];
layout.itemSize = CGSizeMake(280, 280);
layout.minimumInteritemSpacing = 0;
layout.minimumLineSpacing = 0;
layout.scrollDirection = UICollectionViewScrollDirectionHorizontal;
// add a custom UICollectionViewController to the window
vc = [[ViewController alloc] initWithCollectionViewLayout:layout];
self.window.rootViewController = vc;
self.window.backgroundColor = [UIColor yellowColor];
[self.window makeKeyAndVisible];
return YES;
}
@end
The center of the collectionView can be found using this nifty method: CGPoint point = [self. view convertPoint:*yourCollectionView*. center toView:*yourCollectionView]; Now set up a rule, that if the cell's center is further than x away, the size of the cell is for example the 'normal size', call it 1.
An object that manages an ordered collection of data items and presents them using customizable layouts.
Turns out the solution to this was actually quite simple. I just needed to overlap the UICollectionViewCell
cells by enough pixels to have them still show within the collectionView's frame after the paged scrolling finishes. The relevent code was
layout.itemSize = CGSizeMake(300, 300);
layout.minimumLineSpacing = -20.0;
And I subclassed the UICollectionViewFlowLayout
and overrode the (CGSize)collectionViewContentSize
method to return the non-overlapped size of the cells.
Many thanks for the tip about using a negative minimumLineSpacing. I created a tester application which uses a collection view cell loaded from a xib file. The cell has a transparent background and an “inner” view for the cell's content.
In this way, a custom flow layout is not necessary.
https://github.com/j4johnfox/CollectionViewTester
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With