Detect touch of UIImage added as subview of UIScrollView - iphone

I have UIScrollView with many UIImageViews.I need to drag and drop image from UIScrollView to another view. Outside the scrollView touch is worked. But inside scroll view touch is not worked. I used touchesBegan,touchesMoved etc method. Please help me.
-(IBAction)selectBut:(id)sender
{
scrollView = [[UIScrollView alloc]initWithFrame:CGRectMake(x,y,w,h)];
scrollView.userInteractionEnabled = YES;
int y = 0;
for (int i = 0; i < [myArray count]; i++) {
UIImageView *image = [[UIImageView alloc]initWithFrame:CGRectMake(0, y, 75, 30)];
image.userInteractionEnabled = YES;
y=y+35;
[scrollView addSubview:image];
}
[self.view addSubview:scrollView];
[scrollView setContentSize:CGSizeMake(150, 300)]
}
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
if ([touch tapCount] == 1) {
NSLog(#"One touch !!");
}
}

you need to customize the UIImageView with your own view inherited from UIImageView. Provide touch methods in that customized subclass and add it on your UIScrollView..
Subviews of UIScrollview will never call touchesBegan method directly. You need to customized with subview to get touchesBegan properties of that added subview/customized view.
I mean to say take subclass of ImageView like
CustomImageView *imageView = [[CustomImageView alloc] initWithFrame:CGRectMake(0, 0, 200, 200)];
[imageView setUserInteractionEnabled:YES];
[scrollView addSubview:imageView];
[imageView release];
CustomImageView class is should be inherited from UIImageView like
#interface CustomImageView : UIImageView
{
}
in # .m File
#import "CustomImageView.h"
#implementation CustomImageView
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
}
return self;
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
NSLog(#"%s", __FUNCTION__);
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
if ([touch tapCount] == 2) {
drawImageView.image = nil;
return;
}
}

Add a Tap gesture recognizer to the scroll view for enabling touch inside scroll view:
UITapGestureRecognizer *singlTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(methodName:)];
singlTap.cancelsTouchesInView = NO; //Default value for cancelsTouchesInView is YES, which will prevent buttons to be clicked
[scrollViewName addGestureRecognizer:singlTap];
then write your code in specified method.
-(void)methodName:(UITapGestureRecognizer *)gesture
{
//your code here
}

I don't know if this help you. But try to set the exclusiveTouch property of the UIImageView to YES.

Did you add your scrollview as an IBOutlet? If its from xib and as you say touches are available outside the scroll and not within, I guess you might have accidentally unchecked userInteractionEnabled for the scrollview which inhibits touch events. And you have added UIImageViews as subviews to UIScrollView. For UIImageView you have to first set userInteractionEnabled to YES and then add any gestures if necessary to get events or use the touchesBegan, touchesMoved methods. Unless you set interaction enabled you wont receive touch events on UIImageView. If the parent view I mean the UIScrollView's interaction is disabled you wont get touches on UIImageView too. Hope this helps :)

Related

Touch event on uimageview added as subview to parent view

I have added the view programmatically in the main view. And in the parent view i am adding imageview as a subview programmatically. Now I have set the touch event for imageview on click but its not working. It is not detecting the touch event on click. I am using the following code of touch event of imageview.
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
if ([touch view] == originalphoto)
{
[fullview setHidden:NO];
[self.view addSubview:fullview];
[setimage setImage:image];
}
}
Do anyone has idea that how to set touch event of imageview which has been added programmatically?
Thanks alot.
Why dont you use a gesture? it is lot easier. You could use the UITapGestureRecognizer and let it work for you: http://developer.apple.com/library/ios/#DOCUMENTATION/UIKit/Reference/UITapGestureRecognizer_Class/Reference/Reference.html
//Add gesture to your view
UITapGestureRecognizer *Tap= [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(ResignResponder:)];
[tempV addGestureRecognizer:Tap];
[Tap release];
//method will be called on tapping the view
-(void)ResignResponder:(UIGestureRecognizer*)recognizer {
[LocSearchField resignFirstResponder];
[self.view sendSubviewToBack:tempV];
}
UITouch *touch = [[event allTouches] anyObject];
CGPoint location = [touch locationInView:UIIMAGEVIEW];// uiimageview object
touchx = location.x;
touchy = location.y;
NSLog(#" x= %i ", touchx);
NSLog(#"y = %i",touchy);
Maybe you need to set property imageView.userInteractionEnabled = YES?

find which view was clicked

I have a view controller where there are several uiview object. I need to know on which uiview user have tapped. how is this possible? any guidance will help a lot....
Thanks
Pankaj
Here is what you can do to get what you wanted ..... In this example i have created 7 views
UITapGestureRecognizer* gestureRecognizer;
UIView* myView;
for (int i = 0; i < 8; i++)
{
gestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(doSomthing:)];
gestureRecognizer.numberOfTapsRequired = 1;//or what ever you want
myView = [[UIView alloc] initWithFrame:CGRectMake(10, i*30, 30, 28)];
myView.backgroundColor = [UIColor redColor];
myView.tag = 100+i;
[self.view addSubview:myView];
[myView addGestureRecognizer:gestureRecognizer];
[myView release];
[gestureRecognizer release];
}
Now you need to implement the method like this
-(void)doSomthing:(id)sender
{
UIView* temp = [(UITapGestureRecognizer*)sender view];
// here you get the view you wanted
NSLog(#"view number :%d",temp.tag);
}
I think this should help you
Set a tag for every view to keep track of them.
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
// We only support single touches, so anyObject retrieves just that touch from touches
UITouch *touch = [touches anyObject];
NSLog(#"view %i", [touch view].tag);
}
you can add gestures to the uiview objects to find which object has been touched. see the documentation.
http://developer.apple.com/library/ios/#documentation/uikit/reference/UIGestureRecognizer_Class/Reference/Reference.html
for specific code just comment.
U can probably add a custom button with a tag on top of each view. Then u can know which view is tapped based on the button tag.
pls take a look at this. It may help.
http://www.iphonedevsdk.com/forum/iphone-sdk-development/13041-touch-event-subview.html

Issues in handling touches on subviews(uiviews) in UIScrollView

I have craeted a UIScrollView using code and i have created subviews which i am creating dynamically from the DB that are added to the array of views and to the UIScrollviews.I am using touchesBegan and touchesMoved methods.The subview which i am selecting is not recognized,but the control comes into touchesBegan and touches moved method.I have posted the code below.Please anybody help me to overcome from this issue.
I have created the scrollview through code and i have subviews in an array named "arrayofviews".these subviews are the same views which are in the array.I am able to move these subviews which are from the DB on a normal view,but when i added these views to the scrollview its not working.
I have tried so many solutions which are in the net,but i couldn't get a proper solution.
.m file
- (void)viewDidAppear:(BOOL)animated
{
scrollview=[[UIScrollView alloc]initWithFrame:CGRectMake(0, 0, 320, 374)];
scrollview.backgroundColor=[UIColor clearColor];
[scrollview setScrollEnabled:YES];
[scrollview setContentSize:CGSizeMake(300, 600)];
scrollview.showsVerticalScrollIndicator = YES;
scrollview.delaysContentTouches=NO;
.
.
.
.
//here i am retrieving the controls from the DB and adding into the "arrayofviews" array which is an NSMutableArray
//I have added subviews in this part to the scroll like
[scrollview addSubview:vw1];
[scrollview addSubview:vw2];
.
.
.
scrollview.userInteractionEnabled=NO;
scrollview.scrollEnabled=FALSE;
[self.view addSubview:scrollview];
[self.view bringSubviewToFront:scrollview];
}
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
scrollview.userInteractionEnabled=YES;
[self.nextResponder touchesBegan:touches withEvent:event];
UITouch *touch = [[event allTouches] anyObject];
CGPoint touchLocation;
touchLocation.x=scrollview.contentOffset.x;
touchLocation.y=scrollview.contentOffset.y;
for(UIView *vw in arrayOfViews)
{
vw.userInteractionEnabled=YES;
if([touch view]==vw)
{
vw.center=touchLocation;
}
}
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event //method to intiate the touch events
{
[self.nextResponder touchesMoved:touches withEvent:event];
UITouch *touch = [[event touchesForView:scrollview] anyObject];
CGPoint touchLocation1;
touchLocation1.x=scrollview.contentOffset.x;
touchLocation1.y=scrollview.contentOffset.y;
for(UIView *vw in arrayOfViews)
{
if([touch view]==vw)
{
vw.center=touchLocation1; //statement to move the control
}
}
}
change the line
scrollview.userInteractionEnabled=NO;
to
scrollview.userInteractionEnabled=YES;
reason
userInteractionEnabled tells the device, whether to accept touch events. As you disabled the touch on scrollView then how it could recived touches events...
cheers!!!

touchesBegan doesnt get detected

I have a viewcontroller like the following. But the touchsBegan doestnt get detected.
Can anyone plz tell me what is wrong.
- (id)init
{
if (self = [super init])
self.view = [[[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]] autorelease];
return self;
}
-(void) viewWillAppear:(BOOL)animated
{
overlay = [[[UIImageView alloc] initWithImage:[UIImage imageNamed:#"overlay.png"]] autorelease];
[self.view addSubview:overlay];
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
// Detect touch anywhere
UITouch *touch = [touches anyObject];
// Where is the point touched
CGPoint point = [touch locationInView:self.view];
NSLog(#"pointx: %f pointy:%f", point.x, point.y);
// Was a tab touched, if so, which one...
if (CGRectContainsPoint(CGRectMake(1, 440, 106, 40), point))
NSLog(#"tab 1 touched");
else if (CGRectContainsPoint(CGRectMake(107, 440, 106, 40), point))
NSLog(#"tab 2 touched");
else if (CGRectContainsPoint(CGRectMake(214, 440, 106, 40), point))
NSLog(#"tab 3 touched");
}
Touches are only called on UIViews. This means you have to subclass UIView and put your touchesBegan:withEvent: code in this subclass. You're using the code inside an UIViewController and this doesn't get any touches itself because it's not an object on screen. A controller is just for the application logic behind a view.
As chriB said touches are detected only on views and as u access it in a controller its not detected.
also FYI, the touches wont be detected on any views you add over the base view.
ie: if u have a view and u add a scroll view or a table view over it, then the touches wont be detected over this added regions. same goes for buttons, textfields etc. Touch is detected only wen its done exactly on the base view.

Why I cannot get correct class of a custom class through isKindOfClass?

I've created a custom class AnimalView which is a subclass of UIView containing a UILabel and a UIImageView.
#interface AnimalView : UIView {
UILabel *nameLabel;
UIImageView *picture;
}
Then I added in several AnimalView onto the ViewController.view. In the touchesBegan:withEvent: method, I wanted to detect if the touched object is an AnimalView or not. Here is the code for the viewController:
#implementation AppViewController
- (void)viewDidLoad {
UIScrollView *scrollView = [[UIScrollView alloc] initWithFrame:...
[self.view addSubview scrollview];
for (int i = 0; i<10; i++) {
AnimalView *newAnimal = [[AnimalView alloc] init];
// customization of newAnimal
[scrollview addSubview:newAnimal;
}
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
UIView *hitView = touch.view;
if ([hitView isKindOfClass:[AnimalView class]]) {
AnimalView *animal = (AnimalView *)hitView;
[animal doSomething];
}
}
However, nothing happened when I clicked on the animal. When I checked the class of hitView by NSLog(#"%#", [hitView class]), it always shows UIView instead of AnimalView. Is it true that the AnimalView changed to a UIView when it is added onto the ViewController? Is there any way I can get back the original class of a custom class?
It's possible that AnimalView doesn't have user interaction enabled and is ignoring the touches. Try setting [myView setUserInteractionEnabled:YES];
Does an AnimalView have UIView subviews within it? They might be the ones picking up the touch events. You could disable the user interaction of those views by inverting the method described by David on all of the subviews of your AnimalView.
If you have subviews in your AnimalView, you can iterate through the superview hierarchy to see if the touch was handled by a subview of your AnimalView by using code like this:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
UIView *hitView = touch.view;
AnimalView *animal = nil;
while (hitView != nil) {
if ([hitView isKindOfClass:[AnimalView class]]) {
animal = (AnimalView *) hitView;
break;
}
hitView = [hitView superview];
}
if (animal) {
[animal doSomething];
}
}