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;
}
}
Related
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!
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];
}
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.
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.
I use the following code to swipe left and right with a UISwipeGestureRecognizer to show photos in my app in a similar way to iPhoto.
CATransition *animation = [CATransition animation];
[animation setDuration:0.5];
[animation setType:kCATransitionPush];
[animation setSubtype:kCATransitionFromRight];
[animation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
[[self.imageHolder layer] addAnimation:animation forKey:#"SwitchToView"];
This slides the next image in and the old image out like shown in the pictures below:
Image One:
Transition:
Image Two:
I was wondering how to make this like iPhoto when it dawned on me I should use a UIPanGestureRecognizer instead.
I need to 'control' the animation with my finger in the way iPhoto does, namely by allowing me to start dragging to the next image and then reverse the drag direction. Also, in a similar way to iPhoto I'd like the next image to slide in if I release my finger when more of the next image is showing than the first image (this HASN'T happened in the transition picture above and if I released my finger at this point in iPhoto it would slide back to the first image.
I've never used a UIPanGestureRecognizer before so if anybody can help me out that'd be great.
EDIT:
Using the code provided by Levi, I have created a solution that works nicely with 3 sample images. For anybody else who is interested in using a UIPanGestureRecognizer, the code is:
Interface:
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController <UIGestureRecognizerDelegate>
{
int imageIndex;
}
#property (nonatomic, strong) UIImageView* imageView;
#property (nonatomic, strong) UIImageView* leftImageView;
#property (nonatomic, strong) UIImageView* rightImageView;
#end
Implementation:
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self->imageIndex = 0;
float xFactor;
UIInterfaceOrientation currentOrientation = self.interfaceOrientation;
if(UIInterfaceOrientationIsLandscape(currentOrientation)){
xFactor = 256;
}
else{
xFactor = 0;
}
self.imageView = [[UIImageView alloc] initWithFrame:self.view.frame];
self.imageView.contentMode = UIViewContentModeScaleAspectFit;
self.imageView.image = [UIImage imageNamed:#"69B4356B-1CB2-4A2F-867E-9C086251DF11-12668-0000036A534E9B6D"];
self.imageView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
CGRect leftFrame = self.view.frame;
leftFrame.origin.x -= leftFrame.size.width+xFactor;
self.leftImageView = [[UIImageView alloc] initWithFrame:leftFrame];
self.leftImageView.contentMode = UIViewContentModeScaleAspectFit;
self.leftImageView.image = [UIImage imageNamed:#"42517D93-F8BF-42E7-BB44-53B099A482AA-12668-0000036A49BCECAA"];
self.leftImageView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
CGRect rightFrame = self.view.frame;
rightFrame.origin.x += rightFrame.size.width+xFactor;
self.rightImageView = [[UIImageView alloc] initWithFrame:rightFrame];
self.rightImageView.contentMode = UIViewContentModeScaleAspectFit;
self.rightImageView.image = [UIImage imageNamed:#"C6AC2508-243B-464B-A71F-96DD7F18673D-12668-00000369F3AFD3FC"];
self.rightImageView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
[self.view addSubview:self.imageView];
[self.view addSubview:self.leftImageView];
[self.view addSubview:self.rightImageView];
UIPanGestureRecognizer *recognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(handlePan:)];
[self.view addGestureRecognizer:recognizer];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
- (void)handlePan:(UIPanGestureRecognizer *)recognizer {
if (recognizer.state == UIGestureRecognizerStateEnded) {
CGRect leftFrame = self.leftImageView.frame;
CGRect currentFrame = self.imageView.frame;
CGRect rightFrame = self.rightImageView.frame;
float duration = 0.0;
float factor;
UIInterfaceOrientation currentOrientation = self.interfaceOrientation;
if(UIInterfaceOrientationIsPortrait(currentOrientation)){
factor = 768;
}
else{
factor = 1024;
}
if (self.imageView.center.x < 0) { // Present the right image
duration = 0.3 * ABS(self.rightImageView.frame.origin.x / factor);
leftFrame.origin.x = -2 * factor;
currentFrame.origin.x = -1 * factor;
rightFrame.origin.x = 0;
self->imageIndex = 1;
} else if (self.imageView.center.x > factor) { // Present the left image
duration = 0.3 * ABS(self.leftImageView.frame.origin.x / factor);
leftFrame.origin.x = 0;
currentFrame.origin.x = factor;
rightFrame.origin.x = 2 * factor;
self->imageIndex = -1;
} else { // leave the middle image
duration = 0.3 * ABS(self.imageView.frame.origin.x / factor);
leftFrame.origin.x = -1 * factor;
currentFrame.origin.x = 0;
rightFrame.origin.x = factor;
self->imageIndex = 0;
}
[UIView animateWithDuration:duration
delay:0
options:UIViewAnimationOptionCurveEaseInOut
animations:^{
self.leftImageView.frame = leftFrame;
self.imageView.frame = currentFrame;
self.rightImageView.frame = rightFrame;
} completion:^(BOOL finished) {
}];
} else {
CGPoint translation = [recognizer translationInView:recognizer.view];
CGPoint leftCenter = self.leftImageView.center;
CGPoint currentCenter = self.imageView.center;
CGPoint rightCenter = self.rightImageView.center;
leftCenter.x += translation.x;
currentCenter.x += translation.x;
rightCenter.x += translation.x;
self.leftImageView.center = leftCenter;
self.imageView.center = currentCenter;
self.rightImageView.center = rightCenter;
[recognizer setTranslation:CGPointMake(0, 0) inView:self.imageView];
}
}
- (void)willAnimateRotationToInterfaceOrientation:
(UIInterfaceOrientation)toInterfaceOrientation
duration:(NSTimeInterval)duration
{
CGPoint leftCenter = self.leftImageView.center;
CGPoint currentCenter = self.imageView.center;
CGPoint rightCenter = self.rightImageView.center;
if(UIInterfaceOrientationIsPortrait(toInterfaceOrientation)){
leftCenter.x = 384+(((-self->imageIndex)-1)*768);
currentCenter.x = 384+((-self->imageIndex)*768);
rightCenter.x = 384+(((-self->imageIndex)+1)*768);
}
else{
leftCenter.x = 512+(((-self->imageIndex)-1)*1024);
currentCenter.x = 512+((-self->imageIndex)*1024);
rightCenter.x = 512+(((-self->imageIndex)+1)*1024);
}
self.leftImageView.center = leftCenter;
self.imageView.center = currentCenter;
self.rightImageView.center = rightCenter;
}
#end
You can add a UIPanGestureRecognizer to your image view. You would have a method assigned to it where you do something like:
- (void)handlePan:(UIPanGestureRecognizer *)recognizer {
if (recognizer.state == UIGestureRecognizerStateEnded) {
} else {
CGPoint translation = [recognizer translationInView:recognizer.view];
CGPoint center = recognizer.view.center;
UIImageView *imageViewToPresent = nil;
if (translation.x > 0) {
imageViewToPresent = [self leftImageView];
} else {
imageViewToPresent = [self leftImageView];
}
CGPoint actualCenter = recognizer.view.center;
CGPoint nextCenter = imageViewToPresent.center;
actualCenter.x += translation.x;
nextCenter.x += translation.x;
recognizer.view.center = actualCenter;
imageViewToPresent.view.center = nextCenter;
[recognizer setTranslation:CGPointMake(0, 0) inView:self.imageView];
}
}
In the UIGestureRecognizerStateEnded part, you can decide which picture to show.
Or just use a ScrollView with paging enabled. It should have the same effect. However, it would require to have all the images loaded at the same time. Using Pan Recognizer, you need 3 image views tops (left, right, current).
Hope this helps!
EDIT:
In the header file you should add 2 more Image Views:
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController <UIGestureRecognizerDelegate>
#property (nonatomic, strong) UIImageView* imageView;
#property (nonatomic, strong) UIImageView* leftImageView;
#property (nonatomic, strong) UIImageView* rightImageView;
#end
The implementation would be:
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.imageView = [[UIImageView alloc] initWithFrame:self.view.frame];
self.imageView.contentMode = UIViewContentModeScaleAspectFit;
self.imageView.image = [UIImage imageNamed:#"69B4356B-1CB2-4A2F-867E-9C086251DF11-12668-0000036A534E9B6D"];
self.imageView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
CGRect leftFrame = self.view.frame;
leftFrame.origin.x -= leftFrame.size.width;
self.leftImageView = [[UIImageView alloc] initWithFrame:leftFrame];
self.leftImageView.contentMode = UIViewContentModeScaleAspectFit;
self.leftImageView.image = [UIImage imageNamed:#"42517D93-F8BF-42E7-BB44-53B099A482AA-12668-0000036A49BCECAA"];
self.leftImageView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
CGRect rightFrame = self.view.frame;
rightFrame.origin.x += rightFrame.size.width;
self.rightImageView = [[UIImageView alloc] initWithFrame:rightFrame];
self.rightImageView.contentMode = UIViewContentModeScaleAspectFit;
self.rightImageView.image = [UIImage imageNamed:#"C6AC2508-243B-464B-A71F-96DD7F18673D-12668-00000369F3AFD3FC"];
self.rightImageView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
[self.view addSubview:self.imageView];
[self.view addSubview:self.leftImageView];
[self.view addSubview:self.rightImageView];
UIPanGestureRecognizer *recognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(handlePan:)];
[self.view addGestureRecognizer:recognizer];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
- (void)handlePan:(UIPanGestureRecognizer *)recognizer {
if (recognizer.state == UIGestureRecognizerStateEnded) {
CGRect leftFrame = self.leftImageView.frame;
CGRect currentFrame = self.imageView.frame;
CGRect rightFrame = self.rightImageView.frame;
float duration = 0.0;
if (self.imageView.center.x < 0) { // Present the right image
duration = 0.3 * ABS(self.rightImageView.frame.origin.x / self.view.frame.size.width);
leftFrame.origin.x = -2 * self.view.frame.size.width;
currentFrame.origin.x = -1 * self.view.frame.size.width;
rightFrame.origin.x = 0;
} else if (self.imageView.center.x > self.view.frame.size.width) { // Present the left image
duration = 0.3 * ABS(self.leftImageView.frame.origin.x / self.view.frame.size.width);
leftFrame.origin.x = 0;
currentFrame.origin.x = self.view.frame.size.width;
rightFrame.origin.x = 2 * self.view.frame.size.width;
} else { // leave the middle image
duration = 0.3 * ABS(self.imageView.frame.origin.x / self.view.frame.size.width);
leftFrame.origin.x = -1 * self.view.frame.size.width;
currentFrame.origin.x = 0;
rightFrame.origin.x = self.view.frame.size.width;
}
[UIView animateWithDuration:duration
delay:0
options:UIViewAnimationOptionCurveEaseInOut
animations:^{
self.leftImageView.frame = leftFrame;
self.imageView.frame = currentFrame;
self.rightImageView.frame = rightFrame;
} completion:^(BOOL finished) {
}];
} else {
CGPoint translation = [recognizer translationInView:recognizer.view];
CGPoint currnetCenter = self.imageView.center;
CGPoint leftCenter = self.leftImageView.center;
CGPoint rightCenter = self.rightImageView.center;
currnetCenter.x += translation.x;
leftCenter.x += translation.x;
rightCenter.x += translation.x;
self.imageView.center = currnetCenter;
self.leftImageView.center = leftCenter;
self.rightImageView.center = rightCenter;
[recognizer setTranslation:CGPointMake(0, 0) inView:self.imageView];
}
}
#end
Of course it still need work (e.g. to support more than 3 hardcoded images). It may help you with the rotation issue if you would use IBOutlets, and set the auto resizing masks from the Interface Builder.
Have fun!
If you want a scrolling behaviour like the Photos application you shouldn't use a UIGestureRecognizer at all. Use a UIPageViewController with UIPageViewControllerTransitionStyleScroll, or if you need to support versions lower than iOS6, use a UIScrollView.
Check out Apple's sample project PhotoScroller for an example using UIScrollView.