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 ;)
Related
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!!
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:
...
}
}
I have used the animated images on image view concept. It is working fine.Now whenever when I touch that image view I want to check which image is placed on that image view. How should I do this. I have used the following code to make the images animated.
addimage.animationImages=[NSArray arrayWithObjects:
[UIImage imageNamed:#"Softindia.png"],
[UIImage imageNamed:#"images.png"],
nil];
addimage.animationDuration=25.0;
addimage.animationRepeatCount=0;
[addimage startAnimating];
[self.view addSubview:addimage];
Now what should I do on the touch event of image view. Please provide me some solution to resolve this.
Thanks in advance.
UITapGestureRecognizer *tapGesture =
[[[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(imagetap)] autorelease];
[imgview addGestureRecognizer:tapGesture];
-(void)imagetap
{
// your code what ever you want on touch
}
I am affraid that there is no such property inside UIImage which help you to find image name.
you can use this tricky method for solving your problem.
create an property
#property(nonatomic, retain) NSMutableArray * imageArray;
and then synthesis in .m file
#synthesis imageArray
afterward perform following action
self.imageArray = [[NSMutableArray alloc] init];
UIImage *myImage1 = [UIImage imageNamed:#"Softindia.png"];
[imageArray addObject:myImage1];
//Add Second Image
UIImage *myImage2 = [UIImage imageNamed:#"images.png"];
[imageArray addObject:myImage2];
addimage.animationImages= imageArray;
and where ever you are getting your image check do following action
UIImage image = addimage.image;
index = [imageArray indexOfObject:image];
if(index == 0){
//Do action for softindia.png
}
else {
//Do action for images.png;
}
I have implemented UITapGestureRecognizer on UIImageView, It is working on first tap. On First Tap, I am hiding that image and starting animation. Once the animations are completed, i am showing the image again. But After setting setHidden:FALSE, I am not getting the Tap event of that UIImageView.
Following is the code I am using :
- (void)viewDidLoad{
[super viewDidLoad];
defaultDogView= [[UIImageView alloc] initWithFrame:CGRectMake(3, 270, 110, 210)];
[defaultDogView setImage:[UIImage imageNamed:#"dog1.png"]];
defaultDogView.userInteractionEnabled = YES;
[self addGestureRecognizersToPiece:defaultDogView];
[self.view addSubview:defaultDogView];
}
- (void)addGestureRecognizersToPiece:(UIImageView *)piece
{
NSLog(#"in Gesture");
UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(singleTapPiece:)];
[tapGesture setDelegate:self];
[piece addGestureRecognizer:tapGesture];
[tapGesture release];
UILongPressGestureRecognizer *longPressGesture = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:#selector(longPressPiece:)];
[piece addGestureRecognizer:longPressGesture];
[longPressGesture release];
NSLog(#"%#", [piece gestureRecognizers]);
}
- (void)singleTapPiece:(UITapGestureRecognizer *)gestureRecognizer
{
NSLog(#"Image Tapped");
/** Hide the default Image and start the animation ***/
[defaultDogView setHidden:TRUE];
/***Animating the Dog***/
[dogArray addObject:[SpriteHelpers setupAnimatedDog:self.view numFrames:69 withFilePrefix:#"dog" withDuration:(12) ofType:#"png" withValue:0]];
dogView = [dogArray objectAtIndex:0];
//[self addGestureRecognizersToPiece:dogView];
[self performSelector:#selector(callBubbleUpdater) withObject:nil afterDelay:5.5];
}
-(void)showDogFrame{
NSLog(#"%#",[defaultDogView gestureRecognizers]);
[defaultDogView setHidden:FALSE];
defaultDogView.userInteractionEnabled = YES;
}
When view is hidden or its alpha component is zero that view won't receive any UIGestureRecognizers.
I can suggest to use next approach if you need to hide some view (let's name it touchableView) but want it to respond to gestures:
Create backgroundView with the same frame as touchableView:
UIView *backgroundView = [[UIView alloc] initWithFrame:touchableView.frame];
Set background color of backgroundView to clearColor:
backgroundView.backgroundColor = [UIColor clearColor];
Reset position of touchableView:
CGRect frame = touchableView.frame;
frame.origin.x = 0;
frame.origin.y = 0;
Disable user interaction of touchableView:
touchableView.userInteractionEnabled = NO;
Add touchableView as subview to backgroundView:
[backgroundView addSubview:touchableView];
Add appropriate gesture recognizers to backgroundView.
Add backgroundView to view that you want.
Now you can hide touchableView but you will still receive gesture recognizers.
I don't test this but I think it should work.
sure
when UIImageView is hidden. it does not receive any touch events
set alpha zero for uiimageview
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