Reputation: 55
Hi I am trying to add a UIView on top of UICollectionView. My idea is, when you click a single CollectionViewCell then it will show a UIView with information in the same screen. In that way you don't need to go another view and come back to the UICollectionView.
I tried this code:
UICollectionViewController.m
- (void)viewDidLoad
{
[super viewDidLoad];
UIView *subview = [[UIView alloc] initWithFrame:CGRectMake(0, 70, self.collectionView.frame.size.width, 200)];
subview.backgroundColor = [UIColor blackColor];
[collectionView addSubview:subview];
[collectionView bringSubviewToFront:subview];
[collectionView setContentInset:UIEdgeInsetsMake(subview.frame.size.height, 0, 0, 0)];
}
But it seems like when I scroll; the UIView also scrolling with CollectionViewCells.
What could be the solution for my idea.
Thanks
Upvotes: 0
Views: 2976
Reputation: 4444
I did something similar to display a larger version of an image contained in a collection view. I added the view to self.view instead of the collection view. It may be a bit more than you want but it might give you some ideas.
You can put your detail info on the presented view instead of the image like I have.
Since I was displaying images I copied the image in the collection view cell, added a background view on top of the collection view (added to self.view, not the collection view) and added a blurred snapshot of the existing background. I then added a copy of the image in the collection view on top of this view in the same position onscreen as the collection view cell. I Then scaled the image copy up to 300x300 and centered the image onscreen.
I also added a fullscreen button on top of the view, so when you tap anywhere on screen the detail view will be dismissed.
This effect makes it look as if the cell is growing to display the larger image from its position on screen, and shrinks back to it's position on screen when closed.
I implemented the behavior in the collectionView:didSelectItemAtIndexPath method delegate method
-(void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(@"Selected Item at index: %ld", (long)indexPath.row);
// get the cell's frame in the collection view
UICollectionViewLayoutAttributes *attributes = [self.photoCollection layoutAttributesForItemAtIndexPath:indexPath];
CGRect cellRect = attributes.frame;
// take a snapshot of our background for our blurred background image
UIImage *blurImage = [self.view snapshotImage];
blurImage = [blurImage applyLightEffect];
// create our image view for our blur image
UIImageView *blurImgView = [[UIImageView alloc] initWithImage:blurImage];
[blurImgView setFrame:self.view.bounds];
// create our backing view that will contain all the views created here
UIView *backingView = [[UIView alloc] initWithFrame:self.view.bounds];
backingView.tag = 417985;
// add our blur image to our backing view
[backingView addSubview:blurImgView];
[self.view addSubview:backingView];
// convert the cells frame to self.view coordinates and setup our centerpoint from the selected frame
self.selectedFrame = [self.photoCollection convertRect:cellRect toView:self.view];
self.selectedCenter = CGPointMake( self.selectedFrame.origin.x + (self.selectedFrame.size.width * 0.5),
self.selectedFrame.origin.y + (self.selectedFrame.size.height * 0.5));
// create a copy of the image in our collection view to scale up
UIImage *growImage = [[self.onScreenImages objectForKey:@(indexPath.row)] copy];
UIImageView *growImgView = [[UIImageView alloc] initWithFrame:self.selectedFrame];
growImgView.tag = 77;
[growImgView setImage:growImage];
growImgView.layer.cornerRadius = 10.0;
growImgView.clipsToBounds = YES;
// set our blurred background hidden initially
blurImgView.alpha = 0.0;
// add our grow image to our backing view
[backingView addSubview:growImgView];
// create a button to dismiss our enlarged view (it's invisible and the size of our view)
UIButton *dismissBtn = [UIButton buttonWithType:UIButtonTypeCustom];
dismissBtn.frame = self.view.bounds;
[dismissBtn addTarget:self action:@selector(dismissDetailView:) forControlEvents:UIControlEventTouchUpInside];
[backingView addSubview:dismissBtn];
// adjust the position of the image center for visual reasons, move higher for larger phones
CGFloat imgYPos = self.view.center.y - (IS_IPHONE_3_2_ASPECT_RATIO ? 20 : 50);
// animate our blurred background visible, and grow our image to center
[UIView animateWithDuration:0.2
animations:^{
blurImgView.alpha = 1.0;
growImgView.bounds = CGRectMake(0, 0, 300, 300);
growImgView.center = CGPointMake(self.view.center.x, imgYPos);
}];
}
Here is the implementation of some of the snapshot method used. I put it in a category of UIView that returns an image of it's contents to make a blurred background.
-(UIImage*)snapshotImage
{
// Make an image from the input view.
UIGraphicsBeginImageContextWithOptions(self.bounds.size, NO, 0);
[self.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}
Here is how I dismissed the detail view when you tap anywhere on the view.
-(void) dismissDetailView:(id)sender
{
// get our backing view
UIView *__block backingView = [self.view viewWithTag:417985];
// get our enlarged image
UIImageView *growImg = (UIImageView*)[backingView viewWithTag:77];
// shrink our grow img back to original size and move it back to it's original position
[UIView animateWithDuration:0.3
animations:^{
growImg.bounds = CGRectMake(0, 0, self.selectedFrame.size.width, self.selectedFrame.size.height);
growImg.center = self.selectedCenter;
}
completion:^(BOOL finished)
{
// now that the image is back to it's original size, remove the backing view
[UIView animateWithDuration:0.1
animations:^{
// fade our backing view out
backingView.alpha = 0.0;
}
completion:^(BOOL finished) {
// scrap our backing view
[backingView removeFromSuperview];
backingView = nil;
}];
}];
}
Upvotes: 2