Zooming on UIScrollView with paging enabled and multiple images - iphone

I Have a UIScrollview with a UIImageView inside where I scroll from an image to another.
I used the TapToZoom Apple sample code to implement the zoom but whenever I zoom the scrollview starts from the begining rather than the active image.
Here's a piece of my code :
Init and populate the imageview :
table = [[NSMutableArray alloc] initWithCapacity:7];
for(int count = 1; count <= 7; count++)
{
NSString *fileName = [NSString stringWithFormat:#"image%d.jpg", count];
UIImage *image = [UIImage imageNamed:fileName];
[table addObject:image];
if (image == nil) {
break;
}
imageView = [[UIImageView alloc] initWithImage:image];
imageView.userInteractionEnabled = YES;
imageView.multipleTouchEnabled = YES;
Implement Tap Gesture :
UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleSingleTap:)];
UITapGestureRecognizer *doubleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleDoubleTap:)];
The handleDoubleTap method zooms to the center of the the imageView and brings the scrollview to the begigining of the paging.
I searched a lot about this, but was unable to find a way to zoom on the actual displayed image.
Thanks in advance :)

Checkout the PhotoScroller sample from Apple:
http://developer.apple.com/library/ios/#samplecode/PhotoScroller/Introduction/Intro.html

Related

Identifying which subview is tapped

I have a background image (imageView - tag 0) which has been populated by several tagged image subviews (imgView - tagged 1 - ?). I have added a tap recognizer to the main background image, and also tried the subviews as well. I can get to the background tap recognizer routine by tapping, but am unable to identify which subview has been tapped.
Adding the tap recognizer to the background (during View did Load):
UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(singleTapGestureCaptured:)];
[imageView addGestureRecognizer:singleTap];
[imageView setUserInteractionEnabled:YES];
Adding the tap recognizer to each subview as it is loaded:
- (void) showPics{ // display previously stored pictures
NSString *PictureName;
NSNumber *x;
NSNumber *y;
UIImage *viewImage;
tag = 1; // NSInteger declared in .h - background tag is zero
UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(singleTapGestureCaptured:)];
NSLog(#"reading from picFile: %#",self.picFile);
if ([[NSFileManager defaultManager] fileExistsAtPath:self.picFile]){
NSLog(#"FILE Found");
NSMutableArray *picData;
picData = [[NSMutableArray alloc] initWithContentsOfFile:self.picFile];
int count = picData.count/3;
NSLog(#"Count: %d",count);
// set up picture path before cycling through array
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
// cycle to load pictures from file and place on background image
for(int i = 0; i < count; i++) {
PictureName = [picData objectAtIndex:i * 3];
NSString *showPic=[documentsDirectory stringByAppendingPathComponent:PictureName];
if ([[NSFileManager defaultManager] fileExistsAtPath:showPic]){
NSLog(#"Loading: %#",PictureName);
}else{
NSLog(#"Picture Does Not Exist");
}
x = [picData objectAtIndex:i * 3 + 1]; // x coord
y = [picData objectAtIndex:i * 3 + 2]; // y coord
viewImage = [UIImage imageWithContentsOfFile:showPic];
// find center of displayed image and place picture there
imgView = [[[UIImageView alloc] initWithFrame:CGRectMake([x floatValue] - 225,[y floatValue] - 172.5, 450, 345)] autorelease];
[imgView setImage:viewImage];
[imgView setContentMode:UIViewContentModeCenter];
[imgView addGestureRecognizer:singleTap];
[imgView setUserInteractionEnabled:YES];
imgView.tag = tag;
[imageView addSubview:imgView];
tag++;
NSLog(#"Tag: %d",tag);
}
[picData release];
}else{
NSLog(#"Did not find File");
}
}
The routine that is called with a tap anywhere:
- (void)singleTapGestureCaptured:(UITapGestureRecognizer *)sender{
NSLog(#"singleTapGestureCaptured - SUBVIEWS: %d", [imageView.subviews count]);
NSLog(#"TAG: %d",sender.view.tag);
}
This correctly gives me the number of subviews, but always returns "TAG: 0" unless I tap on the last added subview. What I need to know is the correct format for accessing the tapped subview's TAG so I can make it active and move it around, or any other suggestions as to how to do this.
I'm not sure enough to say that, but I guess the point is your tag variable doesn't change. If the tag variable is not global for the whole ".m" file, there's no way it saves its value within different functions or methods. Try declaring it in the ".h" file and give it some other name (ex. Tag or tagValue) so that the compiler could differ what it should return (the tag of a variable or your variable), then add self.Tagor self.tagValue (whatever you name it) every time you assign it to an int. Good luck and let me know if it works.
Put a breakpoint/NSLog the tag value of your imgView. The code snippet doesn't tell the scope of your tag variable (tag++). It seems it is not getting updated.
imgView.tag = tag;
Note, the sender.view in singleTapGestureCaptured method should always give your the topmost imgView (subview) since you are adding TapGestureRecognizer to all imgViews (subviews). In general, when the topmost subview doesn't add (register) any gesture in those cases the gesture passed on to the underlying subviews/parent views in order until someone handles it in the view stack.
EDIT: (After the additional code posted)
You need to create separate UITapGestureRecognizer object and add them to each subview. However all of them can use same #selector method.
So, move this line inside the for loop..
UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(singleTapGestureCaptured:)];
just above
[imgView addGestureRecognizer:singleTap];
//I'm not fan of this but this worked for me
//you can create new imageView and pass tag of tapped subview
//for example some imageView that is subview of a view
//first:
UIImageView *imageView;
imageView.tag = 0;
UITapGestureRecognizer *itemTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(imageTap:)];
[imageView addGestureRecognizer:itemTap];
[someView addSubview:imageView];
//in the action selector imageTap:
-(void)imageTap:(id)sender{
if ([(UIGestureRecognizer *)sender view].tag == 0) {
UIImage *selectedImage;
selectedImage.frame = [[(UIGestureRecognizer *)sender view] viewWithTag:0].frame;
selectedImage.image = [UIImage imageNamed:#"newImage.png"];
//replace with the old:
[someView addSubview:selectedImage];
}}
GOODLUCK ;)

Replacing image in UIScrollView on selected item

I created simple UIScrollView that have images. Each time an image pressed i want to change that image, how can I do it?
I creating this UIScrollView and initializing it with NSMutableArray with images.
UIScrollView *myScroll = [[UIScrollView alloc] initWithFrame: CGRectMake (0,100,200,30)];
NSMutableArray = *images = [NSMutableArray alloc] initWithObjects: img1,img2,img3,nil];
for (int i=0; i<3; i++)
{
UIImageView *imageV = [UIImageView alloc];
[imageV setImage:[images objectAtIndex:i]];
[myScroll addSubview:imageV];
[imageV release];
}
UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget: self action:#selector (changeImg:)];
[myScroll addGestureRecognizer: singleTap];
and the toucing I'm cathing with the touched place on the scroll:
- (void) singleTapGestureCaptured:(UITapGesturerecongnizer *) gesture
{
CGPoint touch = [gesture locationInView:myScroll];
}
By X,Y of touched item i know what image was selected
Here I need to change for example the first image of myScroll...How can i do it?
Add UITapGestureRecognizer on UIImageView and set its userInractionEnabled: YES which is NO by default for UIImageView.
UIScrollView *myScroll = [[UIScrollView alloc] initWithFrame: CGRectMake (0,100,200,30)];
NSMutableArray = *images = [NSMutableArray alloc] initWithObjects: img1,img2,img3,nil];
for (int i=0; i<3; i++)
{
//In your question you didn't set `imageView` frame so correct it
UIImageView *imageV = [[UIImageView alloc]initWithFrame:yourFrame];
[imageV setImage:[images objectAtIndex:i]];
[imageV setUserInteractionEnabled:YES];
UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget: self action:#selector (changeImg:)];
[imageV addGestureRecognizer: singleTap];
[myScroll addSubview:imageV];
[imageV release];
}
After adding all imageView successfully you get them click like this :-
-(void)changeImg:(id)sender
{
UIGestureRecognizer *recognizer = (UIGestureRecognizer*)sender;
UIImageView *imageView = (UIImageView *)recognizer.view;
[imageView setImage:[UIImage imageNamed:#"anyImage.png"]];
}
Your application will crash because you are accessing the index 3, but there is not any object at index 3.
UIScrollView *myScroll = [[UIScrollView alloc] initWithFrame: CGRectMake (0,100,200,30)];
NSMutableArray = *images = [NSMutableArray alloc] initWithObjects: img1,img2,img3,nil];
[myScroll addSubview:[images objectAtIndex:0];
[myScroll addSubview:[images objectAtIndex:1];
[myScroll addSubview:[images objectAtIndex:2];
Now you can access the image view with tagValue
-(void)changeImg :(UIGestureRecognizer*)recog
{
UIScrollView *scroll = (UIScrollView*)recog.view;
CGPoint point = scroll.contentOffset;
int imagetag = (point.y/scroll.frame.size.height);
UIImageView *image=(UIImageView*)[[scroll subviews] objectAtIndex:imagetag];
NSLog(#"Image tag = %d",image.tag);
image.image=[UIImage imageNamed:#"Icon-72.png"];
}
A simple implementation will be, if you use a custom button and change its image on its IBAction.. Still you can addGesture to ur UIImageView too and on the
if(recognizer.state == UIGestureRecognizerStateBegan)
you can change the image on runtime.
I hope this helps. Cheers!!

How to get tag value for an imageview in ipad

Hi i have an ipad app in that i have so many small images on view. each imageview having tag value. now my job is when ever the user touch any imageview which are avaialble on view we have to fetch that particular imageview tag value in ipad.
Add a TapGesture for image. Then you can log it to see what is the tag of the image.To be able fetch that particular imageview tag value.
Like this:
NSInteger i;
for (i=0; i<10; i++)
{
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(x, y, width, height)];
imageView.userInteractionEnabled = YES;
imageView.tag = i;
NSLog(#"%d", imageView.tag);
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(imageTag:)];
[imageView addGestureRecognizer:tap];
}
- (void)imageTag:(id)sender {
switch (((UIGestureRecognizer *)sender).view.tag)
{
case 0:
...
case 1:
...
}
}

facing issue for touch down event for UIImageView again

If My Story Board contains
View
|_my UIIMageView 1
|
|_my UIImageView 2
I can handle the touch down event by following the solution at this post
However, if my Story Board is changed to
Scroll View
|_my UIIMageView 1
|
|_my UIImageView 2
Now I can not detect the touch down event on one of these UIImageView...
Please help me on this issue..
I have used :
UITapGestureRecognizer *touch;
UIImageView *anImageView = [[UIImageView alloc] initWithFrame:CGRectMake(20, 20, 100, 100)];
anImageView.image = [UIImage imageNamed:#"iad.png"];
[anImageView setUserInteractionEnabled:TRUE];
anImageView.tag = 1001 ;
touch = [[[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(test)] autorelease];
touch.numberOfTapsRequired = 1;
[anImageView addGestureRecognizer:touch];
[scrollView addSubview:anImageView];
[anImageView release];
- (void) test:(UIGestureRecognizer *)sender
{
UIImageView *imageView = (UIImageView *)sender.view;
switch (imageView.tag)
{
case 1001:
// your code
break;
case 1002:
// your code
break;
}
}
Probably not the answer you're looking for, but you should think about using UIButtons instead of UIImageViews.
Each UIButton have an UIImageView inside plus all the touch events with it.

Do something to selected image in scroll view

I try to make following: Horizontal list of images, that I can select and do something with it. For example flip image around x axis. I know how to rotate image. I created scrollview and load it with images. I added event handler when I tap on image. But I don't know how to do something with tapped image. How to code method to do something with tapped image?
- (void)viewDidLoad {
[super viewDidLoad];
img1 = [UIImage imageNamed:#"imgTest.jpg"];
img2 = [UIImage imageNamed:#"imgTest2.jpg"];
arrayOfImages = [[NSMutableArray alloc] init];
[arrayOfImages addObject:img1];
[arrayOfImages addObject:img2];
[arrayOfImages addObject:img1];
[arrayOfImages addObject:img2];
scrollView = [[UIScrollView alloc] init];
scrollView.scrollEnabled = YES;
scrollView.pagingEnabled = YES;
scrollView.directionalLockEnabled = YES;
scrollView.showsVerticalScrollIndicator = NO;
scrollView.showsHorizontalScrollIndicator = NO;
scrollView.delegate = self;
scrollView.backgroundColor = [UIColor blueColor];
scrollView.autoresizesSubviews = YES;
scrollView.frame = CGRectMake(0, 0, 320, 128);
[self.view addSubview:scrollView];
UIImage *imageToAdd;
int x = 0;
int y = 0;
for(imageToAdd in arrayOfImages)
{
UIImageView *temp = [[UIImageView alloc] initWithImage:imageToAdd];
temp.frame = CGRectMake(x, y, 128, 128);
temp.userInteractionEnabled = YES;
x += 135;
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(imageTapped:)];
[temp addGestureRecognizer:tap];
[scrollView addSubview:temp];
}
...
- (void)imageTapped:(UIGestureRecognizer *)sender
{
// how to get reference on selected item in scrollview???
}
A gesture recognizer has a view property that returns the view associated with the recognizer. Since you know that it'll be a UIImageView you can simply cast it and use it as in:
UIImageView *iv = (UIImageView *)[sender view];
And your image can then be queried via:
UIImage *image = [iv image];
If you need to know the index in your array, there are two ways: either simply use [arrayOfImages indexOfObject:image];, or you can assign tags (numbers) to views and use them. A tag is not used by Apple, it's only here so we developers can "mark" views in some way. For example:
NSInteger counter = 0;
for(imageToAdd in arrayOfImages)
{
UIImageView *temp = [[UIImageView alloc] initWithImage:imageToAdd];
count.tag = counter++;
...
}
Then, in your imageTapped:, you can query the index via tag:
NSInteger index = [imageView tag];