Reputation: 30131
I have the following UICollectionView Controller
My problem is when I zoom into the image, I am able to "scroll past" the image boundary. It is almost exactly similar to this question Keep zoomable image in center of UIScrollView but the answer didn't solve it for me.
From what I understand, I believe this is because the content size of the scrollView isn't set to the size of the image. However, I'm not sure where to set something like self.scrollView.contentSize = self.imageView.image.size
in my subclassed UICollectionViewCell.
Default View
Zoomed and Moved Beyond Image Boundary
My expected behaviour is for the image to sorta bounce back if the user tries to scroll beyond the image.
The relevant code thus far
Imgur Cell Subclass
- (void)awakeFromNib {
self.scrollView.minimumZoomScale = 1;
self.scrollView.maximumZoomScale = 3.0;
self.scrollView.delegate = self;
}
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
{
return self.imageView;
}
View Controller
- (void)viewDidLoad {
[super viewDidLoad];
[self setStyle];
ImgurCellDetail *cell = (ImgurCellDetail *)[self.collectionView cellForItemAtIndexPath:self.indexPath];
cell.scrollView.minimumZoomScale = cell.scrollView.frame.size.width / cell.imageView.frame.size.width;
cell.scrollView.maximumZoomScale = 3.0;
cell.scrollView.contentSize = cell.imageView.image.size;
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[self loadSelectedImage];
}
- (void)loadSelectedImage
{
[self.collectionView scrollToItemAtIndexPath:self.indexPath
atScrollPosition:UICollectionViewScrollPositionCenteredHorizontally
animated:NO];
}
- (ImgurCellDetail *)collectionView:(UICollectionView *)collectionView
cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifier = @"Cell";
ImgurCellDetail *cell = [collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath];
[self resetImage:cell];
cell.imageView.image = [UIImage imageWithContentsOfFile:self.imageArray[indexPath.row]];
[self.collectionView addGestureRecognizer:cell.scrollView.pinchGestureRecognizer];
[self.collectionView addGestureRecognizer:cell.scrollView.panGestureRecognizer];
return cell;
}
-(CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout
sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
// Need this for 3.5"
return self.collectionView.frame.size;
}
- (void)collectionView:(UICollectionView *)collectionView
didEndDisplayingCell:(ImgurCellDetail *)cell
forItemAtIndexPath:(NSIndexPath *)indexPath {
[self.collectionView removeGestureRecognizer:cell.scrollView.pinchGestureRecognizer];
[self.collectionView removeGestureRecognizer:cell.scrollView.panGestureRecognizer];
}
- (void)resetImage:(ImgurCellDetail *)cell {
//reset zoomScale back to 1 so that contentSize can be modified correctly
cell.scrollView.zoomScale = 1;
}
I should probably mention that I have no issues when the Image View is set to aspect fill but as you can see, it's currently set to aspect fit which is where my troubles begin.
Upvotes: 1
Views: 5271
Reputation: 30131
I managed to solve my own bug. I adapted the method found here: http://www.raywenderlich.com/10518/how-to-use-uiscrollview-to-scroll-and-zoom-content into my solution.
The changes I had to make were:
cellForRowIndexPath
That's about it I think.
Upvotes: 0
Reputation: 10938
I think you have to start by setting the contentSize
of the scroll view to match the size of the scaled down size of your image (the size shown in your first screenshot) and not to the actual size of the picture.
// Not this
//cell.scrollView.contentSize = cell.imageView.image.size;
// But this
CGSize originalSize = cell.imageView.image.size;
CGSize sizeToFit = cell.scrollView.bounds.size;
CGFloat scaleDownFactor = MIN(sizeToFit.width / originalSize.width,
sizeToFit.height / originalSize.height);
CGSize scaledDownSize = CGSizeMake(nearbyintf(originalSize.width * scaleDownFactor),
nearbyintf(originalSize.height * scaleDownFactor));
cell.scrollView.contentSize = scaledDownSize;
// Also use scaledDownSize for the viewForZooming
From there you keep adjusting the content insets as done in the answer you linked.
Finally the scroll view's actual size may not be fully adjusted yet in viewDidLoad
!
Upvotes: 1