Bounds and anchoring of programmatic UIScrollView with zooming - iphone

So, I've managed to create a UIScrollView with zooming method programmatically, but I'm kind of stuck how to solve an issue I'm having with zooming:
When I zoom in or out the point at where it expands/retracts does not happen where I do the pinch gesture, it happens on a corner.
After zooming in or out, it will leave extra space outside the bounds, and I cannot scroll the image more than half the width & height of the image.
Other than this, I'm so close to getting it working 100%. I've tried playing around with achorpoints, but it looks like the scroll view and image view does not respond to this.
Here is the important stuff in the code listing:
UIScrollView *mapScrollView;
UIImageView *mapImageView;
CGFloat lastScale = 0;
NSMutableArray *map_List;
- (id)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
mainMenuAppDelegate *del = (mainMenuAppDelegate *)[[UIApplication sharedApplication] delegate];
map_List = [[NSMutableArray alloc] init];
[map_List addObject:#"Pacific_Map_8bit.png"];
[map_List addObject:#"Atlantic_Map_8bit.png"];
CGRect mapScrollViewFrame = CGRectMake(0, 0, 1024, 768);
mapScrollView = [[UIScrollView alloc] initWithFrame:mapScrollViewFrame];
mapScrollView.contentSize = CGSizeMake(2437, 1536);
UIImage *mapImage = [UIImage imageNamed:[map_List objectAtIndex:mapNum]];
mapImageView = [[UIImageView alloc] initWithImage: mapImage];
mapScrollView.bounces = NO;
[mapImage release];
[mapScrollView addSubview:mapImageView];
[self addSubview:mapScrollView];
mapImageView.userInteractionEnabled = YES;
UIPinchGestureRecognizer *pinchRecognizer = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:#selector(scale:)];
[mapImageView addGestureRecognizer:pinchRecognizer];
[pinchRecognizer release];
}
return self;
}
// the scale method thats triggered to zoom when pinching
-(void)scale:(id)sender {
if([(UIPinchGestureRecognizer*)sender state] == UIGestureRecognizerStateEnded) {
lastScale = 1.0;
return;
}
CGFloat scale = 1.0 - (lastScale - [(UIPinchGestureRecognizer*)sender scale]);
NSLog(#"map scale %f", scale);
CGFloat mapWidth = mapImageView.frame.size.width;
CGFloat mapHeight = mapImageView.frame.size.height;
NSLog(#"map width %f", mapWidth);
if(scale>=1 & mapWidth<=4000 || scale<1 & mapWidth>=1234){
CGAffineTransform currentTransform = [(UIPinchGestureRecognizer*)sender view].transform;
CGAffineTransform newTransform = CGAffineTransformScale(currentTransform, scale, scale);
[[(UIPinchGestureRecognizer*)sender view] setTransform:newTransform];
lastScale = [(UIPinchGestureRecognizer*)sender scale];
}
mapScrollView.contentSize = CGSizeMake(mapWidth, mapHeight);
}
Thanks!

UIScrollView has built-in zooming support. All you need to do is set the minimumZoomScale and maximumZoomScale properties, and return a view to be used for zooming using viewForZoomingInScrollView.

Related

When Rotating UIImageView The Image Moves Off Screen/Out of View

I've got a view on screen with a UIImageView inside it. The user can pan, scale, and rotate.
I have a rotation gesture setup, and everything is fine with rotation except for when rotating the image moves off the screen/out of the view.
Any idea what would cause this to behavior? The expected behavior I'm looking for is when you rotate the image it does not move at all (other than rotating).
I've tried setting an anchor point of the layer of the parent view, but it doesn't seem to be helping any.
EDIT: I've put some logging on the rotation gesture and what's happening is the image views center (X) is what is getting off hence it going off the screen.
Why would this coordinate change upon rotation? The Y is staying the same. I've even tried turning the other gestures off and it's definitely something whacky with the rotation gesture.
Code Below:
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
CALayer *l = [self.viewCase layer];
[l setMasksToBounds:YES];
[l setCornerRadius:30.0];
self.imgUserPhoto.userInteractionEnabled = YES;
[self.imgUserPhoto setClipsToBounds:NO];
UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(panDetected:)];
panRecognizer.maximumNumberOfTouches = 1;
[self.view addGestureRecognizer:panRecognizer];
UIPinchGestureRecognizer *pinchRecognizer = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:#selector(pinchDetected:)];
[self.view addGestureRecognizer:pinchRecognizer];
UIRotationGestureRecognizer *rotationRecognizer = [[UIRotationGestureRecognizer alloc] initWithTarget:self action:#selector(rotationDetected:)];
[self.view addGestureRecognizer:rotationRecognizer];
UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(tapDetected:)];
tapRecognizer.numberOfTapsRequired = 2;
[self.view addGestureRecognizer:tapRecognizer];
panRecognizer.delegate = self;
pinchRecognizer.delegate = self;
rotationRecognizer.delegate = self;
}
- (void)panDetected:(UIPanGestureRecognizer *)panRecognizer
{
CGPoint translation = [panRecognizer translationInView:self.view];
CGPoint imageViewPosition = self.imageView.center;
imageViewPosition.x += translation.x;
imageViewPosition.y += translation.y;
self.imageView.center = imageViewPosition;
[panRecognizer setTranslation:CGPointZero inView:self.view];
}
- (void)pinchDetected:(UIPinchGestureRecognizer *)pinchRecognizer
{
CGFloat scale = pinchRecognizer.scale;
self.imageView.transform = CGAffineTransformScale(self.imageView.transform, scale, scale);
pinchRecognizer.scale = 1.0;
}
- (void)rotationDetected:(UIRotationGestureRecognizer *)rotationRecognizer
{
CGFloat angle = rotationRecognizer.rotation;
self.imageView.transform = CGAffineTransformRotate(self.imageView.transform, angle);
rotationRecognizer.rotation = 0.0;
}
- (void)tapDetected:(UITapGestureRecognizer *)tapRecognizer
{
[UIView animateWithDuration:0.25 animations:^{
self.imageView.center = CGPointMake(CGRectGetMidX(self.view.bounds), CGRectGetMidY(self.view.bounds));
self.imageView.transform = CGAffineTransformIdentity;
}];
}
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
return YES;
}
Maybe because the pan gesture is also getting called : try setting the maximumNumberOfTouches to 1 on your UIPanGestureRecognizer

Zooming UIImageView in UIScrollView goes out of bounds

I've successfully implemented zooming of UIImageView in my UIScrollView but I have faced with a strange problem that irritates me.
Basically, when I zoom in the image
I can pan the view to actually scroll out of the image border and I'm left with a black area like this:
And as I zoom in more I can make the black border to fill the whole screen!
Meanwhile in the iPhone Photo app you can't zoom out the actual image. What's wrong here in my implementation?
It looks like this:
UIImage *imageToDisplay = [UIImage imageWithData:tmpImageData];
imageViewMain.image = imageToDisplay;
imageViewMain.frame = CGRectMake(0, 0, scrollViewMain.frame.size.width, scrollViewMain.frame.size.height);
imageViewMain.contentMode = UIViewContentModeScaleAspectFit;
scrollViewMain.delegate = self;
scrollViewMain.minimumZoomScale = 1.0;
scrollViewMain.maximumZoomScale = 9.0;
scrollViewMain.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
scrollViewMain.contentSize = imageViewMain.frame.size;
[self.view addSubview:scrollViewMain];
[scrollViewMain addSubview:imageViewMain];
And I also implement this method:
- (UIView*)viewForZoomingInScrollView:(UIScrollView *)scrollView
{
return imageViewMain;
}
Thanks in advance!
EDIT:
When I first load the view I shrink my UIImageView to fit the scroll view and the image looks like this:
Just try this code.... change some code where it required... use UIPinchGestureRecognizer for your UIImageView and then add this image in your UIScrollView like bellow..
UIImageView *img = [[UIImageView alloc]init];
img.image = [UIImage imageWithData:tmpImageData];
img.userInteractionEnabled = YES;
img.frame = CGRectMake(210,100, 200, 200);/// define frame which you want...
[img sizeToFit];
UIPinchGestureRecognizer *pinchRecognizer = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:#selector(scale:)];
[pinchRecognizer setDelegate:self];
[img addGestureRecognizer:pinchRecognizer];
[pinchRecognizer release];
[scrollViewMain addSubview:img];
[scrollViewMain bringSubviewToFront:img];
[img release];
and just paste this bellow code in your .m file...
#pragma mark GestureRecognizer Methods
-(void)scale:(id)sender
{
UIView *imgTempGest = [sender view];
if([(UIPinchGestureRecognizer*)sender state] == UIGestureRecognizerStateEnded)
{
lastScale = 1.0;
return;
}
CGFloat scale = 1.0 - (lastScale - [(UIPinchGestureRecognizer*)sender scale]);
CGAffineTransform currentTransform = [(UIPinchGestureRecognizer*)sender view].transform;
CGAffineTransform newTransform = CGAffineTransformScale(currentTransform, scale, scale);
[[(UIPinchGestureRecognizer*)sender view] setTransform:newTransform];
[imgTempGest setTransform:newTransform];
lastScale = [(UIPinchGestureRecognizer*)sender scale];
}
Here for LastScale just define that variable in .h file like bellow...
CGFloat lastScale;
i hope this helpful to you...
Is the original image contains that border in top and bottom?. You can use the same code over there the output is not wrong if the actual image contains that black top and bottom black area. And add this code also,
scrollView.scrollEnabled = YES
also change,
scrollView.contentSize = imageView.bounds.size;
Also you are providing a zoom scale of 9. That much is needed for you?. Change it to 3 or 4 and try. Your problem will be fixed

Rotate Zooming ImageView in ScrollView?

I have a UIScrollView that has a zooming UIImageView, ie it implements:
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
{
return self.imageView;
}
I'm trying to add a UIRotationGestureRecognizer to this imageView and I do it as follows:
_rotationGestureRecognizer = [[UIRotationGestureRecognizer alloc] initWithTarget:self action:#selector(rotate:)];
[self.imageView addGestureRecognizer:_rotationGestureRecognizer];
-(void)rotate:(id)sender
{
UIRotationGestureRecognizer *rotationGestureRecognizer = [(UIRotationGestureRecognizer*)sender retain];
if(rotationGestureRecognizer.state == UIGestureRecognizerStateEnded)
{
self.lastRotation = 0.0;
return;
}
CGFloat rotation = 0.0 - (self.lastRotation - rotationGestureRecognizer.rotation);
rotationGestureRecognizer.view.transform = CGAffineTransformRotate(rotationGestureRecognizer.view.transform, rotation);
self.lastRotation = rotationGestureRecognizer.rotation;
[rotationGestureRecognizer release];
}
I'm just wondering, is it possible to even do this? It seems the UIScrollView is blocking the touches to my UIImageView because nothing is happening. Does Apple recommend to not do this with a zooming view in a UIScrollView?
Following code is working.Add gesture to scrollView instead of imageView.
UIRotationGestureRecognizer* _rotationGestureRecognizer = [[UIRotationGestureRecognizer alloc] initWithTarget:self action:#selector(rotate:)];
[self.scrollView addGestureRecognizer:_rotationGestureRecognizer];
Swift 5 Version:
let rotationGestureRecognizer = UIRotationGestureRecognizer(target: self, action: #selector(self.rotate(_:)))
scrollView.addGestureRecognizer(rotationGestureRecognizer)
-(void)rotate:(UIRotationGestureRecognizer *)sender
{
[self bringSubviewToFront:[(UIRotationGestureRecognizer*)sender view]];
if([(UIRotationGestureRecognizer*)sender state] == UIGestureRecognizerStateEnded)
{
lastRotation = 0.0;
return;
}
CGFloat rotation = 0.0 - (lastRotation - [(UIRotationGestureRecognizer*)sender rotation]);
CGAffineTransform currentTransform = [(UIPinchGestureRecognizer*)sender view].transform;
CGAffineTransform newTransform = CGAffineTransformRotate(currentTransform, rotation);
[[(UIRotationGestureRecognizer*)sender view] setTransform:newTransform];
lastRotation = [(UIRotationGestureRecognizer*)sender rotation];
lastRotation = [(UIRotationGestureRecognizer*)sender rotation];
}

Issue with UIPinchGestureRecognizer and UIImageView

I am trying to pinch an image via UIPinchGestureRecognizer but , the problem is my code does not work properly and actually it could not zoom my image
-(void) pinching: (UIPinchGestureRecognizer *) sender {
CGAffineTransform myTransformation =
CGAffineTransformMakeScale(sender.scale, sender.scale);
sender.view.transform = myTransformation;
}
- (void)viewDidLoad
{
UIPinchGestureRecognizer *pinch =
[[UIPinchGestureRecognizer alloc]
initWithTarget:self
action:#selector(pinching:)];
pinch.delegate = self;
[imageBG addGestureRecognizer:pinch];
[imageBG setUserInteractionEnabled:YES];
[imageBG setMultipleTouchEnabled:YES];
}
Try using a UIScrollView.
To do this, create it
self.scrollView = [[UIScrollView alloc] initWithFrame:...];
self.scrollView.delegate = self;
self.scrollView.maximumZoomScale = 2.0; // adjust as you need
self.scrollView.minimumZoomScale = 0.5; // adjust as you need
[self.scrollView addSubview:self.imageView];
and add the delegate method:
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView {
return self.imageView;
}
just take one variable in .h file like bellow..
CGFloat lastScale;
and use this type of code...
in viewWillAppear: method just add it..
- (void)viewWillAppear:(BOOL)animated
{
UIPinchGestureRecognizer *pinchRecognizer = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:#selector(scale:)];
[pinchRecognizer setDelegate:self];
[yourImageView addGestureRecognizer:pinchRecognizer];
}
-(void)scale:(id)sender {
if([(UIPinchGestureRecognizer*)sender state] == UIGestureRecognizerStateEnded) {
lastScale = 1.0;
return;
}
CGFloat scale = 1.0 - (lastScale - [(UIPinchGestureRecognizer*)sender scale]);
CGAffineTransform currentTransform = [(UIPinchGestureRecognizer*)sender view].transform;
CGAffineTransform newTransform = CGAffineTransformScale(currentTransform, scale, scale);
[[(UIPinchGestureRecognizer*)sender view] setTransform:newTransform];
yourImageView.transform = newTransform
lastScale = [(UIPinchGestureRecognizer*)sender scale];
}
try this code also..
You need to add a scrollView to enable zooming. Add your imageView as a subView of the scroll view. Set the delegate for UIScrollViewDelegate to self. Implement the delegate methods.
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
{
//return the imageview here
return self.imageView;
}
Scale your imageview here:
- (CGRect)zoomRectForScrollView:(UIScrollView *)scrollView withScale:(float)scale withCenter:(CGPoint)center
You can refer this example from Apple .

UIRotationGestureRecognizer on UIImageview

How to rotate UIImageView with two fingure touch in iOS SDK..as I know this is very simple but because of I am new in this technology so cant understand...
How to use UIRotationGestureRecognizer to implement this...
Please help me to solve this problem...
Thanks.
Code this on view did load or the imageview create function : m_ctrlImgVwShowImage - your's imageview
UIRotationGestureRecognizer *rotationRecognizer = [[[UIRotationGestureRecognizer alloc] initWithTarget:self action:#selector(rotate:)] autorelease];
[rotationRecognizer setDelegate:self];
[m_ctrlImgVwShowImage addGestureRecognizer:rotationRecognizer];
//lastRotation is a cgfloat member variable
-(void)rotate:(id)sender {
if([(UIRotationGestureRecognizer*)sender state] == UIGestureRecognizerStateEnded) {
_lastRotation = 0.0;
return;
}
CGFloat rotation = 0.0 - (_lastRotation - [(UIRotationGestureRecognizer*)sender rotation]);
CGAffineTransform currentTransform = m_ctrlImgVwShowImage.transform;
CGAffineTransform newTransform = CGAffineTransformRotate(currentTransform,rotation);
[m_ctrlImgVwShowImage setTransform:newTransform];
_lastRotation = [(UIRotationGestureRecognizer*)sender rotation];
}