Zooming Imageview in Custom UICollectionViewcell - ios

When zooming UIImageView in custom UICollectionViewCell entire cell is zoomed. I want the UIImageView to zoomed as in the photo gallery in the iPhone photos.
#define widthOfBlackTransVw 30
#define ZOOM_STEP 2.0
#implementation DetailedImageCell
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
self.scrollView = [UIScrollView new];
self.scrollView.frame = CGRectMake(0, 0, self.frame.size.width, self.frame.size.height);
self.scrollView.delegate = self;
self.scrollView.userInteractionEnabled = YES;
self.scrollView.bouncesZoom = YES;
[self addSubview:self.scrollView];
self.imageView = [UIImageView new];
self.imageView.frame = self.scrollView.frame;
self.imageView.userInteractionEnabled = YES;
self.imageView.clipsToBounds = YES;
[self.scrollView addSubview:self.imageView];
UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleSingleTap:)];
UITapGestureRecognizer *doubleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleDoubleTap:)];
UITapGestureRecognizer *twoFingerTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleTwoFingerTap:)];
[singleTap setNumberOfTapsRequired:1];
[doubleTap setNumberOfTapsRequired:2];
[twoFingerTap setNumberOfTouchesRequired:2];
//Adding gesture recognizer
[self.imageView addGestureRecognizer:singleTap];
[self.imageView addGestureRecognizer:doubleTap];
[self.imageView addGestureRecognizer:twoFingerTap];
[singleTap requireGestureRecognizerToFail:doubleTap];
float minimumScale = 1.0;
self.scrollView.maximumZoomScale = 6.0;
self.scrollView.minimumZoomScale = minimumScale;
self.scrollView.zoomScale = minimumScale;
[self.imageView setContentMode:UIViewContentModeScaleAspectFit];
[self.scrollView setContentSize:self.imageView.bounds.size];
}
return self;
}
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
{
return self.imageView;
}
- (void)scrollViewDidZoom:(UIScrollView *)aScrollView
{
CGFloat offsetX = (self.scrollView.bounds.size.width > self.scrollView.contentSize.width)?
(self.scrollView.bounds.size.width - self.scrollView.contentSize.width) * 0.5 : 0.0;
CGFloat offsetY = (self.scrollView.bounds.size.height > self.scrollView.contentSize.height)?
(self.scrollView.bounds.size.height - self.scrollView.contentSize.height) * 0.5 : 0.0;
self.imageView.center = CGPointMake(self.scrollView.contentSize.width * 0.5 + offsetX,
self.scrollView.contentSize.height * 0.5 + offsetY);
}
- (void)handleDoubleTap:(UIGestureRecognizer *)gestureRecognizer {
// zoom in
float newScale = [self.scrollView zoomScale] * ZOOM_STEP;
if (newScale > self.scrollView.maximumZoomScale){
newScale = self.scrollView.minimumZoomScale;
CGRect zoomRect = [self zoomRectForScale:newScale withCenter:[gestureRecognizer locationInView:gestureRecognizer.view]];
[self.scrollView zoomToRect:zoomRect animated:YES];
}
else{
newScale = self.scrollView.maximumZoomScale;
CGRect zoomRect = [self zoomRectForScale:newScale withCenter:[gestureRecognizer locationInView:gestureRecognizer.view]];
[self.scrollView zoomToRect:zoomRect animated:YES];
}
}
- (void)handleTwoFingerTap:(UIGestureRecognizer *)gestureRecognizer
{
float newScale = [self.scrollView zoomScale] / ZOOM_STEP;
CGRect zoomRect = [self zoomRectForScale:newScale withCenter:[gestureRecognizer locationInView:gestureRecognizer.view]];
[self.scrollView zoomToRect:zoomRect animated:YES];
}
- (CGRect)zoomRectForScale:(float)scale withCenter:(CGPoint)center {
CGRect zoomRect;
// the zoom rect is in the content view's coordinates.
// At a zoom scale of 1.0, it would be the size of the self.scrollView's bounds.
// As the zoom scale decreases, so more content is visible, the size of the rect grows.
zoomRect.size.height = [self.scrollView frame].size.height / scale;
zoomRect.size.width = [self.scrollView frame].size.width / scale;
// choose an origin so as to get the right center.
zoomRect.origin.x = center.x - (zoomRect.size.width / 2.0);
zoomRect.origin.y = center.y - (zoomRect.size.height / 2.0);
return zoomRect;
}
The cell extra space zoom along with UIImage. I need to zoom only the UIImageView.

Related

Blank View when using CGPDF for showing PDF in iOS 9/10 with Objective-C

I have used Quartz Core and CGPDF to show a zoomable PDF in my app for quite some time, but since Xcode 8 and trying to make my app compatible for iOS 9 and 10, the PDF-code seems to have broken. This is the code I have been using:
- (void)loadPDF
{
[self.scrollView removeFromSuperview];
[self.aContentView removeFromSuperview];
[self.tiledLayer removeFromSuperlayer];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *cachePath = [paths objectAtIndex:0];
NSURL *fileURL = [NSURL fileURLWithPath:[cachePath stringByAppendingPathComponent:#"Exmaple.pdf"]];
self.aDocumentRef = CGPDFDocumentCreateWithURL((CFURLRef)CFBridgingRetain(fileURL));
self.aPageRef = CGPDFDocumentGetPage(self.aDocumentRef, 1);
CGRect rect = CGRectMake(0, 0, self.view.bounds.size.width, self.view.bounds.size.height);
self.tiledLayer = [CATiledLayer layer];
self.tiledLayer.delegate = nil;
self.tiledLayer.tileSize = rect.size;
self.tiledLayer.levelsOfDetail = 100;
self.tiledLayer.levelsOfDetailBias = 100;
self.tiledLayer.frame = rect;
self.aContentView = [[UIView alloc] initWithFrame:rect];
[self.aContentView.layer addSublayer:self.tiledLayer];
self.scrollView = [[UIScrollView alloc] initWithFrame:rect];
self.scrollView.delegate = self;
self.scrollView.contentSize = rect.size;
self.scrollView.maximumZoomScale = ZOOM_MAXIMUM;
[self.scrollView addSubview:self.aContentView];
[self.view addSubview:self.scrollView];
[self.aContentView setTag:ZOOM_VIEW_TAG];
UITapGestureRecognizer *doubleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleDoubleTap:)];
UITapGestureRecognizer *twoFingerTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleTwoFingerTap:)];
[doubleTap setNumberOfTapsRequired:2];
[twoFingerTap setNumberOfTouchesRequired:2];
[self.aContentView addGestureRecognizer:doubleTap];
[self.aContentView addGestureRecognizer:twoFingerTap];
float minimumScale = [self.scrollView frame].size.width / [self.aContentView frame].size.width;
[self.scrollView setMinimumZoomScale:minimumScale];
[self.scrollView setZoomScale:minimumScale];
self.aContentView.translatesAutoresizingMaskIntoConstraints = YES;
self.scrollView.translatesAutoresizingMaskIntoConstraints = YES;
}
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollViewLocal
{
return [self.scrollView viewWithTag:ZOOM_VIEW_TAG];
}
- (void)handleDoubleTap:(UIGestureRecognizer *)gestureRecognizer
{
float newScale = [self.scrollView zoomScale] * ZOOM_STEP;
CGRect zoomRect = [self zoomRectForScale:newScale withCenter:[gestureRecognizer locationInView:gestureRecognizer.view]];
[self.scrollView zoomToRect:zoomRect animated:YES];
}
- (void)handleTwoFingerTap:(UIGestureRecognizer *)gestureRecognizer
{
float newScale = [self.scrollView zoomScale] / ZOOM_STEP;
CGRect zoomRect = [self zoomRectForScale:newScale withCenter:[gestureRecognizer locationInView:gestureRecognizer.view]];
[self.scrollView zoomToRect:zoomRect animated:YES];
}
- (CGRect)zoomRectForScale:(float)scale withCenter:(CGPoint)center
{
CGRect zoomRect;
zoomRect.size.height = [self.scrollView frame].size.height / scale;
zoomRect.size.width = [self.scrollView frame].size.width / scale;
zoomRect.origin.x = center.x - (zoomRect.size.width / 2.0);
zoomRect.origin.y = center.y - (zoomRect.size.height / 2.0);
return zoomRect;
}
- (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx
{
CGContextSetRGBFillColor(ctx, 1.0, 1.0, 1.0, 1.0);
CGContextFillRect(ctx, CGContextGetClipBoundingBox(ctx));
CGContextTranslateCTM(ctx, 0.0, layer.bounds.size.height);
CGContextScaleCTM(ctx, 1.0, -1.0);
CGContextConcatCTM(ctx, CGPDFPageGetDrawingTransform(self.aPageRef, kCGPDFCropBox, layer.bounds, 0, true));
CGContextDrawPDFPage(ctx, self.aPageRef);
}
The scroll view shows up but the page is blank. The PDF is loaded from the correct directory. Can anyone give me a hint of what I'm missing? Thanks!

Zoom image and then scroll image to view next image, previous image not zooming out

I want to zoom out image to original size after scroll slider.
I'm using REPagedScrollView library to implement slider.
I have 5 images in slider. Now zoom-in 1st image and then immediately scroll slider to view 2nd image. Then go back to view 1st image. 1st image not zooming out. That image was still in zoom - in mode.
How can i solved this.
Thanks in advance.
I'm using this below code.
-(void)slideShow
{
[scrollView removeFromSuperview];
scrollView = [[REPagedScrollView alloc] initWithFrame:self.scrollVw.bounds];
scrollView.delegate=self;
scrollView.pageControl.pageIndicatorTintColor=[UIColor clearColor];
scrollView.pageControl.currentPageIndicatorTintColor=[UIColor clearColor];
current_page=0;
for(int i=0;i<[self.PhotoImgArr count];i++){
// Image view
image_scroll = [[UIScrollView alloc] initWithFrame:CGRectMake(0,0,self.scrollVw.frame.size.width,self.scrollVw.frame.size.height)];
self.image_view = [[AsyncImageView alloc] initWithFrame:CGRectMake(0,0, image_scroll.frame.size.width, image_scroll.frame.size.height)];
self.image_view.backgroundColor=[UIColor clearColor];
// self.image_view.contentMode = UIViewContentModeScaleAspectFit;
self.image_view.clipsToBounds = true;
self.image_view.userInteractionEnabled = YES;
//self.image_view.image=[UIImage imageNamed:#"Stars"];
self.image_view.imageURL =[NSURL URLWithString:[self.PhotoImgArr objectAtIndex:i]];
doubleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleDoubleTap:)];
[doubleTap setNumberOfTapsRequired:2];
[self.image_view addGestureRecognizer:doubleTap];
// twoFingerPinch = [[UIPinchGestureRecognizer alloc]
// initWithTarget:self
// action:#selector(twoFingerPinch:)];
// [self.image_view addGestureRecognizer:twoFingerPinch];
[image_scroll setDelegate:self];
[image_scroll setShowsHorizontalScrollIndicator:NO];
[image_scroll setShowsVerticalScrollIndicator:NO];
image_scroll.tag=i+1;
// image_scroll.backgroundColor=[UIColor purpleColor];
image_scroll.autoresizingMask=UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight;
self.image_view.autoresizingMask=UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight;
image_scroll.contentSize = CGSizeMake(self.image_view.bounds.size.width-500, self.image_view.bounds.size.height-300);
image_scroll.decelerationRate = UIScrollViewDecelerationRateFast;
[image_scroll setMaximumZoomScale:4.0];
// image_scroll.minimumZoomScale = 1.0;
[image_scroll setZoomScale:[image_scroll minimumZoomScale]];
//image_scroll.zoomScale = 1.0;
[image_scroll addSubview:self.image_view];
[scrollView addPage:image_scroll];
}
scrollView.autoresizingMask=UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight;
scrollView.tag=0;
[self.scrollVw addSubview:scrollView];
[scrollView scrollToPageWithIndex:self.selected_index animated:YES];
}
- (void)twoFingerPinch:(UIPinchGestureRecognizer *)recognizer
{
NSLog(#"twoFingerPinch");
float newScale = [image_scroll zoomScale] / 2.0;
CGRect zoomRect = [self zoomRectForScale:newScale withCenter:[recognizer locationInView:recognizer.view]];
[image_scroll zoomToRect:zoomRect animated:YES];
}
- (void)handleDoubleTap:(UIGestureRecognizer *)gestureRecognizer {
// zoom in
NSLog(#"handleDoubleTap");
UIScrollView *imageScroll = (UIScrollView *)[self.view viewWithTag:self.selected_index+1];
float newScale = [imageScroll zoomScale] * 2.0;
if (newScale > imageScroll.maximumZoomScale){
newScale = imageScroll.minimumZoomScale;
CGRect zoomRect = [self zoomRectForScale:newScale withCenter:[gestureRecognizer locationInView:gestureRecognizer.view]];
[imageScroll zoomToRect:zoomRect animated:YES];
}
else{
newScale = imageScroll.maximumZoomScale;
CGRect zoomRect = [self zoomRectForScale:newScale withCenter:[gestureRecognizer locationInView:gestureRecognizer.view]];
[imageScroll zoomToRect:zoomRect animated:YES];
}
}
#pragma mark Utility methods
- (CGRect)zoomRectForScale:(float)scale withCenter:(CGPoint)center {
CGRect zoomRect;
// the zoom rect is in the content view's coordinates.
// At a zoom scale of 1.0, it would be the size of the imageScrollView's bounds.
// As the zoom scale decreases, so more content is visible, the size of the rect grows.
zoomRect.size.height = [image_scroll frame].size.height / scale;
zoomRect.size.width = [image_scroll frame].size.width / scale;
// choose an origin so as to get the right center.
zoomRect.origin.x = center.x - (zoomRect.size.width / 2.0);
zoomRect.origin.y = center.y - (zoomRect.size.height / 2.0);
return zoomRect;
}
- (void)scrollViewDidScroll:(UIScrollView *)scrollView1
{
UIScrollView *imageScroll = (UIScrollView *)[self.view viewWithTag:self.selected_index+1];
if(scrollView1.tag ==0){
CGFloat pageWidth = scrollView1.frame.size.width;
current_page = floor((scrollView1.contentOffset.x - pageWidth / 2.0) / pageWidth) + 1;
self.selected_index=current_page;
self.lblHeader.text=[NSString stringWithFormat:#"%ld of %lu",self.selected_index+1,(unsigned long)[self.PhotoImgArr count]];
}
else
{
CGFloat offsetX = (imageScroll.bounds.size.width > imageScroll.contentSize.width)?
(imageScroll.bounds.size.width - imageScroll.contentSize.width) * 0.5 : 0.0;
CGFloat offsetY = (imageScroll.bounds.size.height > imageScroll.contentSize.height)?
(imageScroll.bounds.size.height - imageScroll.contentSize.height) * 0.5 : 0.0;
[scrollView1.subviews objectAtIndex:0].center = CGPointMake(imageScroll.contentSize.width * 0.5 + offsetX,imageScroll.contentSize.height * 0.5 + offsetY);
}
}
-(UIView *) viewForZoomingInScrollView:(UIScrollView *)scrollView1
{
if([scrollView1.subviews count]>0){
return [scrollView1.subviews objectAtIndex:0];
}
return nil;
}
ok first of all, don't use REPagedScrollView instead u can set the pages to scrollview by changing the view's x position, and it is useful for your zooming, if u use REPagedScrollView there are some complications that u can't get the subview's as scrollview, instead u get a UIView instance
Better u use normal UIScrollView it is good for your case, and also set the UIPageControl as they are doing in REPagedScrollView as separately in view controller's view.
first set the pages like below
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
_scrollPager = [[UIScrollView alloc] initWithFrame:self.view.bounds];
_scrollPager.delegate=self;
_scrollPager.pagingEnabled = YES;
_current_page=0;
_prev_next_index = 0;
_PhotoImgArr = [[NSMutableArray alloc] initWithObjects:#"00.jpg",#"01.jpg",#"02.jpg",#"03.jpg", nil];
CGSize totalContentSize = CGSizeMake(self.view.bounds.size.width [_PhotoImgArr count], self.view.bounds.size.height);
_scrollPager.contentSize = totalContentSize;
[self.view addSubview:_scrollPager];
[self setUpPager];
}
- (void)setUpPager
{
for(int i=0;i<[self.PhotoImgArr count];i++)
{
// Image view
UIScrollView *image_scroll = [[UIScrollView alloc] initWithFrame:CGRectMake(i * self.view.bounds.size.width, 0, self.view.bounds.size.width, self.view.bounds.size.height)];
UIImageView *image_view = [[UIImageView alloc] initWithFrame:image_scroll.bounds];
image_view.backgroundColor=[UIColor clearColor];
image_view.clipsToBounds = true;
image_view.image = [UIImage imageNamed:_PhotoImgArr[i]];
UITapGestureRecognizer *doubleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleDoubleTap:)];
[doubleTap setNumberOfTapsRequired:2];
[image_scroll setDelegate:self];
[image_scroll setShowsHorizontalScrollIndicator:NO];
[image_scroll setShowsVerticalScrollIndicator:NO];
image_scroll.tag=i;
image_scroll.autoresizingMask=UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight;
image_view.autoresizingMask=UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight;
image_scroll.contentSize = image_scroll.bounds.size;
image_scroll.decelerationRate = UIScrollViewDecelerationRateFast;
image_scroll.minimumZoomScale = 1.0f;
image_scroll.maximumZoomScale = 3.0f;
[image_scroll addSubview:image_view];
[image_scroll addGestureRecognizer:doubleTap];
[_scrollPager addSubview:image_scroll];
}
_scrollPager.autoresizingMask=UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight;
_scrollPager.tag=100;
}
Handle the double tap action like below in same view controller
- (void)handleDoubleTap:(UIGestureRecognizer *)gestureRecognizer
{
// zoom in
NSLog(#"handleDoubleTap");
if(gestureRecognizer.view == _scrollPager) return;
UIScrollView *doubleTapScroll = [self getImageScroller];
if(doubleTapScroll)
{
//zoom
CGPoint pointInView = [gestureRecognizer locationInView:self.view];
CGFloat newZoomScale = doubleTapScroll.zoomScale * 1.5f;
newZoomScale = MIN(newZoomScale, doubleTapScroll.maximumZoomScale);
CGRect rectToZoomTo = CGRectZero;
CGFloat currentZoomScale = doubleTapScroll.zoomScale;
if(currentZoomScale == 1.0f)
{
rectToZoomTo = [self zoomRectForScrollView:doubleTapScroll withScale:newZoomScale withCenter:pointInView];//CGRectMake(x, y, w, h);
}
else if (currentZoomScale >= 1.0f)
{
rectToZoomTo = [self zoomRectForScrollView:doubleTapScroll withScale:1 withCenter:self.view.center];
}
[doubleTapScroll zoomToRect:rectToZoomTo animated:YES];
}
}
and one thing for scrollview u don't need to handle pinch, it will automatillcay handled for zooming.
finally handling of the zoom
#pragma mark Utility methods
- (CGRect)zoomRectForScrollView:(UIScrollView *)scrollView withScale:(float)scale withCenter:(CGPoint)center
{
CGRect zoomRect;
zoomRect.size.height = scrollView.frame.size.height / scale;
zoomRect.size.width = scrollView.frame.size.width / scale;
zoomRect.origin.x = center.x - (zoomRect.size.width / 2.0);
zoomRect.origin.y = center.y - (zoomRect.size.height / 2.0);
return zoomRect;
}
- (void)scrollViewDidScroll:(UIScrollView *)scrollView1
{
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
if(scrollView == _scrollPager)
{
float currentPage = scrollView.contentOffset.x /scrollView.frame.size.width;
if(currentPage != _current_page)
{
_prev_next_index = _current_page;
_current_page = ceil(currentPage);
[self resetScrollerAtViewIndex:_prev_next_index];
}
}
}
-(UIView *) viewForZoomingInScrollView:(UIScrollView *)scrollView1
{
if(scrollView1 == _scrollPager)
return nil;
else
{
UIScrollView *image_scroll = [self getImageScroller];
if(image_scroll)
if([image_scroll.subviews count]>0)
{
return [image_scroll.subviews objectAtIndex:0];
}
}
return nil;
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (UIScrollView *)getImageScroller
{
return [_scrollPager viewWithTag:_current_page];
}
- (void)resetScrollerAtViewIndex:(NSInteger)index
{
UIScrollView *scrollView = [_scrollPager viewWithTag:index];
CGFloat zoomScale = scrollView.zoomScale;
if(zoomScale != 1.0)
[scrollView setZoomScale:1 animated:YES];
}
Edit for zoom out when return to previous or next page
just replace the below method
- (void)resetScrollerAtViewIndex:(NSInteger)index
{
//CGFloat zoomScale = 1.0;
UIScrollView *scrollView = [_scrollPager viewWithTag:index];
CGRect rectToZoomTo = CGRectZero;
rectToZoomTo = [self zoomRectForScrollView:scrollView withScale:1 withCenter:self.view.center];
[scrollView zoomToRect:self.view.bounds animated:YES];
[scrollView setContentOffset:CGPointZero];
[scrollView setContentSize:self.view.bounds.size];
}

Animating UIScrollView with paging

I am having a scrollView having 2 subviews per screen and thus 10 subviews.Paging is disabled right now. Now i want whenever I swipe up the subviews inside scrollviews, they should fill the entire screen and after then, normal scrolling is applicable having 10 views each on one screen with paging enabled.Any help??
const NSUInteger kNumViews= 10;
const CGFloat vScrollObjWidth = 160.0;
const CGFloat vScrollObjHeight = 280.0;
- (void)layoutScrollViews
{
UIView *view = nil;
NSArray *subviews = [scrollView2 subviews];
CGFloat curXLoc = 0;
for (view in subviews)
{
if ([view isKindOfClass:[UIImageView class]] && view.tag > 0)
{
CGRect frame = view.frame;
frame.origin = CGPointMake(curXLoc, 0);
view.frame = frame;
curXLoc += (vScrollObjWidth);
}
}
[scrollView2 setContentSize:CGSizeMake((kNumViews+1) * vScrollObjWidth, scrollView2.bounds.size.height)];
}
- (void)viewDidLoad
{
self.view.backgroundColor = [UIColor viewFlipsideBackgroundColor];
scrollView2.delegate = self;
[scrollView2 setBackgroundColor:[UIColor blackColor]];
scrollView2.scrollEnabled = YES;
for (i = 1; i <= kNumViews; i++)
{
NSString *imageName = [NSString stringWithFormat:#"imageV%d.jpg", i];
UIImage *image = [UIImage imageNamed:imageName];
UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
[imageView sizeToFit];
imageView.layer.borderColor = [UIColor grayColor].CGColor;
imageView.layer.borderWidth = 1.5f;
CGRect rect = imageView.frame;
rect.size.height = vScrollObjHeight;
rect.size.width = vScrollObjWidth;
imageView.frame = rect;
imageView.tag = i;
imageView.userInteractionEnabled = YES;
[scrollView2 addSubview:imageView];
}
[self layoutScrollViews];
self.swipeRecognizerUp = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(scaleMove:)];
[self.swipeRecognizerUp setDelegate:self];
[scrollView2 addGestureRecognizer:self.swipeRecognizerUp];
self.swipeRecognizerDown = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(scaleDown:)];
[self.swipeRecognizerDown setDelegate:self];
[scrollView2 addGestureRecognizer:self.swipeRecognizerDown];
self.swipeRecognizerDown.enabled = NO;
}
-(void)scaleMove:(id)sender {
[[[(UIPanGestureRecognizer*)sender view] layer] removeAllAnimations];
[self.view bringSubviewToFront:[sender view]];
CGPoint velocity = [sender velocityInView:self.view];
if(abs(velocity.y) - abs(velocity.x) > 500 && velocity.y < 0){
CGAffineTransform scale = CGAffineTransformMakeScale(1, 0.82);
CGAffineTransform translate = CGAffineTransformMakeTranslation(0,254);
[sender view].transform = CGAffineTransformConcat(translate, scale);
[UIView animateWithDuration:0.5
animations:^(){
CGAffineTransform scale = CGAffineTransformMakeScale(2, 1.64);
CGAffineTransform translate = CGAffineTransformMakeTranslation(0,-254);
[sender view].transform = CGAffineTransformConcat(translate, scale);
}
completion:nil];
scrollView2.pagingEnabled = YES;
self.swipeRecognizerDown.enabled = YES;
self.swipeRecognizerUp.enabled = NO;
}
}
-(void)scaleDown:(id)sender {
[[[(UIPanGestureRecognizer*)sender view] layer] removeAllAnimations];
[self.view bringSubviewToFront:[sender view]];
CGPoint velocity = [sender velocityInView:self.view];
if(abs(velocity.y) - abs(velocity.x) > 500 && velocity.y > 0){
[sender view].transform = CGAffineTransformMakeScale(2, 1.64);
[UIView animateWithDuration:0.5
animations:^(){
[sender view].transform = CGAffineTransformMakeScale(1.0, 0.82);
}
completion:nil];
scrollView2.pagingEnabled = NO;
self.swipeRecognizerUp.enabled = YES;
self.swipeRecognizerDown.enabled = NO;
}
}

Resize uiscrollview after scaling so as to enable paging

I am having a scrollview containing 2 image views in one page only.I am scaling scrollview so as to cover full screen on tapping.Now i want after scaling, paging should be enabled.But then it skip every alternate image view. Any help would be appreciated.`
kNumViews = 10;
vScrollObjectHeight = 230; // half screen
vScrollObjectWidth = 160; // half screen
{
for (i = 1; i <= kNumViews; i++)
{
NSString *imageName = [NSString stringWithFormat:#"imageV%d.jpg", i];
UIImage *image = [UIImage imageNamed:imageName];
UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
[imageView sizeToFit];
imageView.layer.borderColor = [UIColor grayColor].CGColor;
imageView.layer.borderWidth = 1.5f;
CGRect rect = imageView.frame;
rect.size.height = vScrollObjHeight;
rect.size.width = vScrollObjWidth;
imageView.frame = rect;
imageView.tag = i;
imageView.userInteractionEnabled = YES;
[scrollView2 addSubview:imageView];
}
[self layoutScrollViews];
self.swipeRecognizerUp = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(scaleMove:)];
[self.swipeRecognizerUp setDelegate:self];
[scrollView2 addGestureRecognizer:self.swipeRecognizerUp];
self.swipeRecognizerDown = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(scaleDown:)];
[self.swipeRecognizerDown setDelegate:self];
[scrollView2 addGestureRecognizer:self.swipeRecognizerDown];
self.swipeRecognizerDown.enabled = NO;
}
-(void)scaleMove:(id)sender {
[[[(UIPanGestureRecognizer*)sender view] layer] removeAllAnimations];
[self.view bringSubviewToFront:[sender view]];
CGPoint velocity = [sender velocityInView:self.view];
if(abs(velocity.y) - abs(velocity.x) > 500 && velocity.y < 0){
[sender view].transform = CGAffineTransformMakeScale(1.0, 1.0);
//[sender view].transform = CGAffineTransformMakeTranslation(0, 230);
[UIView animateWithDuration:0.5
animations:^(){
CGAffineTransform scale = CGAffineTransformMakeScale(2.0, 2.0);
CGAffineTransform translate = CGAffineTransformMakeTranslation(0,-230);
[sender view].transform = CGAffineTransformConcat(translate, scale);
//NSLog(#"%f %f",[sender view].frame.size.width,[sender view].frame.size.height);
scrollView2.pagingEnabled = YES;
}
completion:nil];
self.swipeRecognizerDown.enabled = YES;
self.swipeRecognizerUp.enabled = NO;
}
}
}
`
found answer of it...I have set the width of scrollview half and then subclasses the scrollview so as to override pointInside and then normally scaled scrollview.found answer of it...I have set the width of scrollview half and then subclasses the scrollview so as to override pointInside and then normally scaled scrollview.

Zooming UIImageView in a UIScrollView acts weirdly

I have the following problem, guys. I have an app that is pretty much like Apple's PhotoScroller. I want to jump from image to image by swiping the screen. I can do that, but I can't zoom the images. Here's the problem - I have an array with images. If the array has only one object inside, there's no problem with zooming. But if there are more images in the array, they acts weirdly when I try to zoom. The image is not being zoomed and it goes where it wants off the screen. Here is my code:
int pageWidth = 1024;
int pageHeight = 768;
int counter = 0;
self.view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, pageWidth, pageHeight)];
CGRect containerFrame = self.view.frame;
scrollView = [[UIScrollView alloc] initWithFrame:containerFrame];
[self.view addSubview:scrollView];
NSMutableArray *all = [[NSMutableArray alloc] init];
[all addObject:[UIImage imageNamed:#"222.jpg"]];
CGSize scrollSize = CGSizeMake(pageWidth * [all count], pageHeight);
[scrollView setContentSize:scrollSize];
for (UIImage *image in all)
{
UIImage *pageImage = [[UIImage alloc] init];
pageImage = [all objectAtIndex:counter];
CGRect scrollFrame = CGRectMake(pageWidth * counter, 0, pageWidth, pageHeight);
miniScrollView = [[UIScrollView alloc] initWithFrame:scrollFrame];
[scrollView addSubview:miniScrollView];
CGSize miniScrollSize = CGSizeMake(pageImage.size.width, pageImage.size.height);
[miniScrollView setContentSize:miniScrollSize];
UIImageView *tempImageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, pageImage.size.width, pageImage.size.height)];
tempImageView.image = [all objectAtIndex:counter];
self.imageView = tempImageView;
miniScrollView.maximumZoomScale = 3.0;
miniScrollView.minimumZoomScale = 1.0;
miniScrollView.clipsToBounds = YES;
miniScrollView.delegate = self;
miniScrollView.showsHorizontalScrollIndicator = NO;
miniScrollView.showsVerticalScrollIndicator = NO;
miniScrollView.bouncesZoom = YES;
[miniScrollView addSubview:imageView];
counter ++;
}
[scrollView setPagingEnabled:YES];
[scrollView setScrollEnabled:YES];
}
-(UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
{
return imageView;
}
Do you have any ideas what's wrong? Because I am trying to get this work almost 2 weeks.
I also worked on such sort of App. The first thing that you can do is to take a separate subclass of your ScrollView so that all the paging and zooming operations can be handled easily. In your scrollView Class, You can take reference from the following code snippet.
#interface PhotoScrollView : UIScrollView<UIScrollViewDelegate,UIGestureRecognizerDelegate>
{
int finalPhotoWidth;
int finalPhotoHeight;
}
// to contain image
#property (strong, nonatomic) UIImageView *imageView;
- (id)initWithFrame:(CGRect)frame andImage:(UIImage *)photo
{
self = [super initWithFrame:frame];
if (self)
{
// Initialization code
[self initializeScrollViewWithImage:photo];
//setting gesture recognizer for single tap
UITapGestureRecognizer *singleTapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(scrollViewSingleTapped:)];
singleTapRecognizer.delegate = self;
singleTapRecognizer.numberOfTapsRequired = 1;
[self addGestureRecognizer:singleTapRecognizer];
//setting gesture recognizer for Double tap
UITapGestureRecognizer *doubleTapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(scrollViewDoubleTapped:)];
doubleTapRecognizer.delegate = self;
doubleTapRecognizer.numberOfTapsRequired = 2;
[self addGestureRecognizer:doubleTapRecognizer];
[singleTapRecognizer requireGestureRecognizerToFail:doubleTapRecognizer];
singleTapActivated = FALSE;
self.backgroundColor = [UIColor blackColor];
self.minimumZoomScale = 1.0f;
self.maximumZoomScale = 15.0f;
self.zoomScale = 1.0f;
self.delegate = self;
}
return self;
}
//for sizing the frame by giving height and width
-(void)initializeScrollViewWithImage:(UIImage*)photo
{
finalPhotoWidth = photo.size.width;
finalPhotoHeight = photo.size.height;
//Pre-checking of frame and setting the height and width accordingly
if (finalPhotoHeight > self.frame.size.height)
{
// if photo height is bigger than frame height, re-adjust the photo height and width accordingly
finalPhotoHeight = self.frame.size.height;
finalPhotoWidth = (photo.size.width/photo.size.height) * finalPhotoHeight;
}
if (finalPhotoWidth > self.frame.size.width)
{
// if photo width is bigger than frame width, re-adjust the photo height and width accordingly
finalPhotoWidth = self.frame.size.width;
finalPhotoHeight = (photo.size.height/photo.size.width) * finalPhotoWidth;
}
if (finalPhotoHeight < self.frame.size.height && finalPhotoWidth < self.frame.size.width)
{
// if the photo is smaller than frame, increase the photo width and height accordingly
finalPhotoWidth = self.frame.size.width;
finalPhotoHeight = self.frame.size.height;
}
//initialising imageView with the thumbnail photo
self.imageView = [[UIImageView alloc] initWithImage:photo];
self.imageView.contentMode = UIViewContentModeScaleAspectFit;
//setting frame according to the modified width and height
if(!isnan(finalPhotoWidth) && !isnan(finalPhotoHeight))
{
self.imageView.frame = CGRectMake( (self.frame.size.width - finalPhotoWidth) / 2, (self.frame.size.height - finalPhotoHeight)/2, finalPhotoWidth, finalPhotoHeight);
}
// setting scrollView properties
self.contentSize = self.imageView.frame.size;
// add image view to scroll view
[self addSubview:self.imageView];
}
//to deny the simultaneous working of single and double taps
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
return NO;
}
// Gesture handleer for single tap gesture
-(void)scrollViewSingleTapped:(UITapGestureRecognizer *)recognizer
{
if(!singleTapActivated)
{
//do as per requirement
singleTapActivated = TRUE;
}
else
{
//do as per requirement
singleTapActivated = FALSE;
}
}
//for zooming after double tapping
- (void)scrollViewDoubleTapped:(UITapGestureRecognizer*)recognizer
{
//to check whether image is zoomed
if (self.zoomScale != 1.0f)
{
//if image is zoomed, then zoom out
[self setZoomScale:1.0 animated:YES];
self.imageView.frame = CGRectMake( (self.frame.size.width - finalPhotoWidth) / 2, (self.frame.size.height - finalPhotoHeight)/2, finalPhotoWidth, finalPhotoHeight);
[self.observer photoZoomStopped];
}
else
{
// get the point of image which is double tapped
CGPoint pointInView = [recognizer locationInView:self.imageView];
// Get a zoom scale that's zoomed in slightly, capped at the maximum zoom scale specified by the scroll view
CGFloat newZoomScale = self.zoomScale * 4.0f;
newZoomScale = MIN(newZoomScale, self.maximumZoomScale);
// Figure out the rect we want to zoom to, then zoom to it
CGSize scrollViewSize = self.imageView.frame.size;
CGFloat w = scrollViewSize.width / newZoomScale;
CGFloat h = scrollViewSize.height / newZoomScale;
CGFloat x = pointInView.x - (w / 2.0f);
CGFloat y = pointInView.y - (h / 2.0f);
CGRect rectToZoomTo = CGRectMake(x, y, w, h);
[self zoomToRect:rectToZoomTo animated:YES];
}
}
// To re-center the image after zooming in and zooming out
- (void)centerScrollViewContents
{
CGSize boundsSize = self.bounds.size;
CGRect contentsFrame = self.imageView.frame;
if (contentsFrame.size.width < boundsSize.width)
{
contentsFrame.origin.x = (boundsSize.width - contentsFrame.size.width) / 2.0f;
}
else
{
contentsFrame.origin.x = 0.0f;
}
if (contentsFrame.size.height < boundsSize.height)
{
contentsFrame.origin.y = (boundsSize.height - contentsFrame.size.height) / 2.0f;
}
else
{
contentsFrame.origin.y = 0.0f;
}
self.imageView.frame = contentsFrame;
}
//for zooming in and zooming out
- (void)scrollViewDidZoom:(UIScrollView *)scrollView
{
if (self.zoomScale > 1.0f)
{
[self.observer photoZoomStarted];
[self centerScrollViewContents];
}
else
{
self.bouncesZoom = NO;
[self.observer photoZoomStopped];
// for zooming out by pinching
[self centerScrollViewContents];
}
// The scroll view has zoomed, so we need to re-center the contents
}
- (UIView*)viewForZoomingInScrollView:(UIScrollView *)scrollView
{
return self.imageView;
}
Please let me know if it helps. Thanks :)

Resources