Zoom a specific area of a Scrollview - ios

I'm stuck on a case where I want to zooming a part(rect) of a scrollview programatically not by touch or gestures.
CGRect cropRect = CGRectMake(xPos * [UIScreen mainScreen].nativeScale, yPos * [UIScreen mainScreen].nativeScale, width1 * [UIScreen mainScreen].nativeScale, height1 * [UIScreen mainScreen].nativeScale);
[self.scrlVPhoto zoomToRect:cropRect animated:YES];
I've set delegate and also implemented delegate method.
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)aScrollView {
return self.containerView;
}
self.containerView is a view that I want to zoom.
I've tried everything and I'm still confused how to get out of this.
Please some one can help me. Any help is appreciated.
Thanks in advance.

I am going to answer my own question.
I've searched lots of articles and hours of debugging I've found that when scrollview is zoomed then actually its contentSize is increased its zoomScale remain unchanged.
So I just used transform property of the scrollview's subview (i.e. self.containerView) and set scrollview's contentOffset I got what I was looking for.
self.containerView.transform = CGAffineTransformMakeScale(1.8, 1.8); // containerView is subview of scrollview and 1.8 is zoom scale just for eg.
[self.scrlVPhoto setContentOffset:CGPointMake(self.scrlVPhoto.contentOffset.x, (self.scrlVPhoto.contentOffset.y + cropRect.origin.y)) animated:true];

You should add the view which you want to zoom inside the scrollview. Inside the delegate method return the view which you want to zoom.

I have Create the UIImageView, set the Zoom option in imageView when double tap or single tap to UIImageView and the code is given below,
viewDidLoad Method:
UITapGestureRecognizer *doubleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleDoubleTap:)];
[doubleTap setNumberOfTapsRequired:2];
DoubleTab Method:
- (void)handleDoubleTap:(UIGestureRecognizer *)gestureRecognizer {
// zoom in
float newScale = [myscrollview zoomScale] * 2;
if (newScale > self.myscrollview.maximumZoomScale){
newScale = self.myscrollview.minimumZoomScale;
CGRect zoomRect = [self zoomRectForScale:newScale withCenter:[gestureRecognizer locationInView:gestureRecognizer.view]];
[myscrollview zoomToRect:zoomRect animated:YES];
}
else{
newScale = self.myscrollview.maximumZoomScale;
CGRect zoomRect = [self zoomRectForScale:newScale withCenter:[gestureRecognizer locationInView:gestureRecognizer.view]];
[myscrollview 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 imageScrollView's bounds.
// As the zoom scale decreases, so more content is visible, the size of the rect grows.
zoomRect.size.height = [myscrollview frame].size.height / scale;
zoomRect.size.width = [myscrollview 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;
}
And you need the delegate methods are shown below,
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
{
if (vmov==nil)
{
float newwidth;
float newheight;
UIImage *image=detaimageview.image;
if (image.size.height>=image.size.width){
newheight=detaimageview.frame.size.height;
newwidth=(image.size.width/image.size.height)*newheight;
if(newwidth>detaimageview.frame.size.width){
float diff=detaimageview.frame.size.width-newwidth;
newheight=newheight+diff/newheight*newheight;
newwidth=detaimageview.frame.size.width;
}
}
else{
newwidth=detaimageview.frame.size.width;
newheight=(image.size.height/image.size.width)*newwidth;
if(newheight>detaimageview.frame.size.height){
float diff=detaimageview.frame.size.height-newheight;
newwidth=newwidth+diff/newwidth*newwidth;
newheight=detaimageview.frame.size.height;
myscrollview.clipsToBounds = NO;
}
}
CGRect frame;
CGFloat screenWidth;
CGFloat screenHeight;
CGRect screenRect = [[UIScreen mainScreen] bounds];
screenWidth = screenRect.size.width;
screenHeight = screenRect.size.height-64;
frame.size.width = newwidth;
frame.size.height = newheight;
self.myscrollview.contentSize = frame.size;
float x,y;
x=0;
y=0;
if (newheight<screenHeight)
{
x =screenHeight/2-newheight/2;
}
if (newwidth<screenWidth)
{
y =screenWidth/2-newwidth/2;
}
self.detaimageview.frame = CGRectMake(y,x,newwidth,newheight);
return self.detaimageview;
}
return nil;
}
this above codes are zoom the imageView and its working for my Projects,
hope its helpful

Please check this one. Its may be helpful to you
-(void)handlePinchWithGestureRecognizer:(UIPinchGestureRecognizer *)pinchGestureRecognizer{
//[self.superImage_View setAlpha:0.5];
if([pinchGestureRecognizer state] == UIGestureRecognizerStateBegan) {
// Reset the last scale, necessary if there are multiple objects with different scales
lastScale = [pinchGestureRecognizer scale];
}
if ([pinchGestureRecognizer state] == UIGestureRecognizerStateBegan ||
[pinchGestureRecognizer state] == UIGestureRecognizerStateChanged){
CGFloat currentScale = [[[pinchGestureRecognizer view].layer valueForKeyPath:#"transform.scale"] floatValue];
// Constants to adjust the max/min values of zoom
const CGFloat kMaxScale = 2.0;
const CGFloat kMinScale = 1.0;
CGFloat newScale = 1-(lastScale-[pinchGestureRecognizer scale]) ; // new scale is in the range (0-1)
newScale = MIN(newScale, kMaxScale / currentScale);
newScale = MAX(newScale, kMinScale / currentScale);
CGAffineTransform transform = CGAffineTransformScale([[pinchGestureRecognizer view] transform], newScale, newScale);
[pinchGestureRecognizer view].transform = transform;
lastScale = [pinchGestureRecognizer scale]; // Store the previous scale factor for the next pinch gesture call
}
if ([pinchGestureRecognizer state] == UIGestureRecognizerStateEnded) {
[undoList addObject:cropImage];
}
}

Related

How to zoom only visible image in image view not transparent part of image?

I have a scrollView in a UIView and a imageView in the ScrollView.scrollview and imageview have same size.I have set image view content mode is UIViewContentModeScaleAspectFit . when i double tap on image view , image view not zoom only visible image of image view but also zoom transparent portion of image.
I want only zoom visible image of image view.
image_scroll = [[UIScrollView alloc] initWithFrame:CGRectMake(0,0,screen_width,550)];
self.image_view = [[UIImageView 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:#"img1.png"];
doubleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleDoubleTap:)];
[doubleTap setNumberOfTapsRequired:2];
[self.image_view addGestureRecognizer:doubleTap];
[image_scroll setMaximumZoomScale:4.0];
[image_scroll addSubview:self.image_view];
- (void)handleDoubleTap:(UIGestureRecognizer *)gestureRecognizer {
NSLog(#"handleDoubleTap");
float newScale = [image_scroll zoomScale] * 2.0;
if (newScale > image_scroll.maximumZoomScale){
newScale = image_scroll.minimumZoomScale;
CGRect zoomRect = [self zoomRectForScale:newScale withCenter:[gestureRecognizer locationInView:gestureRecognizer.view]];
[image_scroll zoomToRect:zoomRect animated:YES];
}
else{
newScale = imageScroll.maximumZoomScale;
CGRect zoomRect = [self zoomRectForScale:newScale withCenter:[gestureRecognizer locationInView:gestureRecognizer.view]];
[image_scroll 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 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;
}
1.Original image
2.After image zoom
Thanks in advance.
Objective-C
I think you should check for my demo project :
https://github.com/VivekVithlani/PinchZoom-Objective-c.git
I have not implement double tap to zoom, it's only pinch-zoom.
Your problem solved 100%

How to Zoom Image on single tap in an iCarousel View?

I am trying hard to zoom image on single tap, but no success yet. I have a carousel view with 6 images which works great but i want the particular image to zoom/pop-up when tapped on the image in carousel view. Any help will be highly appreciated.
First Declare the TapGestureRegcognizer then addSubview in your UIImageView. use this code in your viewDidLoad:
UITapGestureRecognizer *doubleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleDoubleTap:)];
[doubleTap setNumberOfTapsRequired:1];
[imageview addGestureRecognizer:doubleTap];
then if you click the UIImageView single tap, call the below methods are,
- (void)handleDoubleTap:(UIGestureRecognizer *)gestureRecognizer {
// zoom in
float newScale = [myscrollview zoomScale] * 2;
if (newScale > self.myscrollview.maximumZoomScale){
newScale = self.myscrollview.minimumZoomScale;
CGRect zoomRect = [self zoomRectForScale:newScale withCenter:[gestureRecognizer locationInView:gestureRecognizer.view]];
[myscrollview zoomToRect:zoomRect animated:YES];
}
else{
newScale = self.myscrollview.maximumZoomScale;
CGRect zoomRect = [self zoomRectForScale:newScale withCenter:[gestureRecognizer locationInView:gestureRecognizer.view]];
[myscrollview 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 imageScrollView's bounds.
// As the zoom scale decreases, so more content is visible, the size of the rect grows.
zoomRect.size.height = [myscrollview frame].size.height / scale;
zoomRect.size.width = [myscrollview 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;
}
its working for me, hope its helpful.

Set content size of scrollview relative to transform on zooming by UIPinchGestureRecognizer

I have scrollview and added UIPinchGestureRecognizer to scrollview. Now on gesture event I have zoom in or out scrollview and its handle action is as following :
static float lastScale = 1.0;
- (void)handlePinchGesture:(UIPinchGestureRecognizer *)gestureRecognizer
{
if([gestureRecognizer state] == UIGestureRecognizerStateBegan) {
// Reset the last scale, necessary if there are multiple objects with different scales
lastScale = [gestureRecognizer scale];
}
if ([gestureRecognizer state] == UIGestureRecognizerStateBegan || [gestureRecognizer state] == UIGestureRecognizerStateChanged)
{
CGFloat currentScale = [[[gestureRecognizer view].layer valueForKeyPath:#"transform.scale"] floatValue];
// Constants to adjust the max/min values of zoom
const CGFloat kMaxScale = 2.0;
const CGFloat kMinScale = 1.0;
CGFloat newScale = 1 - (lastScale - [gestureRecognizer scale]);
newScale = MIN(newScale, kMaxScale / currentScale);
newScale = MAX(newScale, kMinScale / currentScale);
CGAffineTransform transform = CGAffineTransformScale([[gestureRecognizer view] transform], newScale, newScale);
[gestureRecognizer view].transform = transform;
lastScale = [gestureRecognizer scale]; // Store the previous scale factor for the next pinch gesture call
}
}
I want to change contentSize in this method. Now, my question is that how to set scrollview content size so that after zoom out I can scroll to see all the content in scrollview.
Please help.
#interface HorizontalScrollView ()
{
UIView *container;
}
#end
#implementation HorizontalScrollView
#synthesize scrlView;
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
container = [[UIView alloc]initWithFrame:CGRectMake(0, 0, self.scrlView.frame.size.width, self.scrlView.frame.size.height)];
UIImage *image = [UIImage imageNamed:#"1.jpeg"];
UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
CGRect rect = imageView.frame;
rect.size.height = 215;
rect.size.width = self.scrlView.frame.size.width;
rect.origin = CGPointMake(0, 0);
imageView.frame = rect;
[container addSubview:imageView];
[scrlView addSubview:container];
self.scrlView.minimumZoomScale=1.0;
self.scrlView.maximumZoomScale=6.0;
self.scrlView.delegate=self;
// set the content size so it can be scrollable
[self.scrlView setContentSize:CGSizeMake(1*self.scrlView.frame.size.width, 0)];
}
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
{
return container;
}

How to add a Gesture Recogniser in imageview in iOS?

i add a UIPanGestureRecognizer to my imageview then Gesture Recognizer is added but my imageview image is panned in to my view i want only image is panned inside of the imageview on in the view how it is possible?
i write a code for that on viewdidload
UIPanGestureRecognizer *pangesture=[[UIPanGestureRecognizer alloc]initWithTarget:self action:#selector(panGestureDetected:)];
[pangesture setDelegate:self];
[self.zoomImage addGestureRecognizer:pangesture];
and method for that is
- (void)panGestureDetected:(UIPanGestureRecognizer *)recognizer
{
UIGestureRecognizerState state = [recognizer state];
if (state == UIGestureRecognizerStateBegan || state == UIGestureRecognizerStateChanged)
{
CGPoint translation = [recognizer translationInView:recognizer.view];
[recognizer.view setTransform:CGAffineTransformTranslate(recognizer.view.transform, translation.x, translation.y)];
[recognizer setTranslation:CGPointZero inView:recognizer.view];
}
}
then imageView image is panned in my View but i want image Panned only inside of imageview if it possible then give me solution.
here my original imageview Size is like as
and when i added UIPanGEstureRecognizer then it look like as
image are panned in View but i want to zoom it inside of imageview size please give me solution for that.
take UIScrollView and add UIImageView inside the scrollview and pangesture on scrollview ..
set delegate for scrollview and do the code
- (UIView*)viewForZoomingInScrollView:(UIScrollView *)scrollView {
// Return the view that we want to zoom
return self.zoomImage;
}
- (void)scrollViewDidZoom:(UIScrollView *)scrollView {
// The scroll view has zoomed, so we need to re-center the contents
[self centerScrollViewContents];
}
- (void)centerScrollViewContents {
CGSize boundsSize = scrollView.bounds.size;
CGRect contentsFrame = self.zoomImage.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.zoomImage.frame = contentsFrame;
}
- (void)scrollViewDoubleTapped:(UITapGestureRecognizer*)recognizer {
// Get the location within the image view where we tapped
CGPoint pointInView = [recognizer locationInView:imageView];
// Get a zoom scale that's zoomed in slightly, capped at the maximum zoom scale specified by the scroll view
CGFloat newZoomScale = scrollView.zoomScale * 1.5f;
newZoomScale = MIN(newZoomScale, scrollView.maximumZoomScale);
// Figure out the rect we want to zoom to, then zoom to it
CGSize scrollViewSize = scrollView.bounds.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);
[scrollView zoomToRect:rectToZoomTo animated:YES];
}
- (void)scrollViewTwoFingerTapped:(UITapGestureRecognizer*)recognizer {
// Zoom out slightly, capping at the minimum zoom scale specified by the scroll view
CGFloat newZoomScale = scrollView.zoomScale / 1.5f;
newZoomScale = MAX(newZoomScale, scrollView.minimumZoomScale);
[scrollView setZoomScale:newZoomScale animated:YES];
}
UIImage object's userInteractEnable is NO by default, so you can't interact with it. Try self.zoomImage.userInteractEnable = YES
Try this:
Add another UIView under the imageView, make its size exactly the same as your imageView. Then set your imageView as this UIView's subview by drag and drop the imageView on top of this UIView (Assuming you are using StoryBoard or xib).
After that, if you are using StoryBoard or xib, then go to Attributes Inspector, select this UIView, tick Click Subviews. If not, just set view.clipsToBounds = YES;

Image is stretching while Pinch

I'm getting images from remote server and displaying in UIImageView then doing pinch gesture to this imageview. But when i pinching image, i'm getting image stretching. It's loosing original resolution and quality.
mmageView=[[UIImageView alloc]initWithFrame:CGRectMake(50,50,150,150)];
[self.view addSubview:mmageView];
UIPinchGestureRecognizer *dbpinchGesture = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:#selector(dbhandlePinch:)];
[mmageView addGestureRecognizer:dbpinchGesture];
UIPinchGesture:
-(void)dbhandlePinch:(UIPinchGestureRecognizer*)recognizer {
if([recognizer state] == UIGestureRecognizerStateBegan) {
// Reset the last scale, necessary if there are multiple objects with different scales
LastScale = [recognizer scale];
}
if ([recognizer state] == UIGestureRecognizerStateBegan ||
[recognizer state] == UIGestureRecognizerStateChanged) {
CGFloat currentScale = [[[recognizer view].layer valueForKeyPath:#"transform.scale"] floatValue];
// Constants to adjust the max/min values of zoom
// const CGFloat kMaxScale = 2.0;
const CGFloat kMinScale = 0.8;
CGFloat newScale = 1 - (LastScale - [recognizer scale]);
// newScale = MIN(newScale, kMaxScale / currentScale);
newScale = MAX(newScale, kMinScale / currentScale);
CGAffineTransform transform = CGAffineTransformScale([[recognizer view] transform], newScale, newScale);
[recognizer view].transform = transform;
LastScale = [recognizer scale]; // Store the previous scale factor for the next pinch gesture call
}
}
For pinch zoom add your imageView in a scrollView and Import UIScrollViewDelegate
- (void)viewDidLoad
{
[super viewDidLoad];
//for pinch gesture
_scrollView.minimumZoomScale = 0.5;
_scrollView.maximumZoomScale = 6.0;
_scrollView.contentSize = CGSizeMake(_imageView.frame.size.width, _imageView.frame.size.height);
_scrollView.delegate = self;
}
-(UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
{
return _imageView;
}
UIScrollView makes supporting the pinch gestures for zooming easy. Better solution in Apple Documentation.

Resources