Detect single tap on UIScrollView containing 'n' UIImageViews - iphone

I am simply trying to get hold of the UIImageView that was tapped on, from the UIScrollView.
I have found 2 ways of achieving the above on the Web.
1st method : create a tap gesture on the uiimageview before adding it to scrollviewer.
This method has not worked for me. the handleSingleTap method never gets called.
I am out of ideas on what I am doing wrong/why this is not working.
UITapGestureRecognizer *singleTap =
[[UITapGestureRecognizer alloc] initWithTarget:self
action:#selector(handleSingleTap:)];
singleTap.numberOfTapsRequired = 1;
[imageView addGestureRecognizer:singleTap];
[singleTap release];
[framesSourceScrollview addSubview:imageView];
[imageView release];
- (void)handleSingleTap:(UIGestureRecognizer *)sender
{
NSLog(#"image tapped!!!");
}
2nd Method : subclass UIScrollView
#interface SingleTapScrollViewer : UIScrollView {
}
#end
#implementation SingleTapScrollViewer
- (id)initWithFrame:(CGRect)frame
{
return [super initWithFrame:frame];
}
- (void) touchesEnded: (NSSet *) touches withEvent: (UIEvent *) event
{
// If not dragging, send event to next responder
if (!self.dragging)
[self.nextResponder touchesEnded: touches withEvent:event];
else
[super touchesEnded: touches withEvent: event];
}
#end
In the ViewController
- (void) touchesEnded: (NSSet *) touches withEvent: (UIEvent *) event
{
// Process the single tap here
NSLog(#"Scroll view single tapped. touches count : %d", touches.count);
UITouch *touch = [touches anyObject];
UIImageView *imgView = (UIImageView*)touch.view;
NSLog(#"tag is %#", imgView.tag);
}
Using this method, the touchesDown responder does get called but the '[touches anyobject]' isn't the UIImageView which was tapped on.
I tried setting the 'tag' on every UIImageView I am adding to the scrollview with an increasing counter but I get back 0 no matter which imageview i tap on.
I am new to cocoa in general and I am not sure how to leverage this responder in any other fashion.
Any suggestions/hints would be great.
thanks in advance.

did you set the userInteractionEnabled=YES on the UIImageView. Its turned off by default.

Related

Touches event for a UIScrollView

How can I get touch event for UIScrollView.I have a UIViewController and I placed a scrollView in viewController.I need to add imageViews to scrollView and if a particular image is clicked it should redirect to its corresponding viewController.
I knew how to add touch event to a UIViewController.But that doesn't work for a scrollView.
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch= [touches anyObject];
if ([touch view] == img1)
{
ViewController2 *viewController2=[[ViewController2 alloc]initWithNibName:#"ViewController2" bundle:nil];
[self presentViewController: viewController2 animated:YES completion:nil];
}
}
HOw can I get touches event for a scrollView ?
The only way to do this is by creating a custom UIScrollView Your custom UIScrollView will be a subclass of UIScrollView.
Also for more options you can check this
Set things like below:
UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(singleTapGestureCaptured:)];
[scrollView addGestureRecognizer:singleTap];
and you get the touch in:
- (void)singleTapGestureCaptured:(UITapGestureRecognizer *)gesture
{
CGPoint touchPoint=[gesture locationInView:scrollView];
}
You can use the ScrollViewDelegate and can use the function "ScrollViewDidScroll" for getting the scrollview scroll event.
Set up a tap gesture recognizer:
UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(singleTapGestureCaptured:)];
[scrollView addGestureRecognizer:singleTap];
- (void)singleTapGestureCaptured:(UITapGestureRecognizer *)gesture
{
CGPoint touchPoint=[gesture locationInView:scrollView];
}

UIScrollView with a UIButton and UITapGestureRecognizer

I've been playing around with this code, but can't get it right.
Current behaviour: I can scroll around freely on a UIScrollView, even when tapping on buttons. When i tap on something that isn't a button, it calls a method (like i want it to), as a result of a UITapGestureRecognizer. However, i have to hold down on a button for a couple of seconds then touch up for it to trigger the button's UIControlEventTouchUpInside.
What I want to happen: Exactly the same, but to be able to touch the UIButton easily, like I can if i turn off the UITapGestureRecognizer on the view it's sitting on.
Here's my code:
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
//...
[cell.xButton addTarget:self action:#selector(xButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
self.delaysContentTouches = YES;
UITapGestureRecognizer *tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleTapFrom:)];
[self addGestureRecognizer:tapGestureRecognizer];
tapGestureRecognizer.delegate = self;
}
}
- (void) handleTapFrom: (UITapGestureRecognizer *)recognizer
{
[self.header removeKeyboard];
}
As stavash suggested, you could do the following:
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
{
UIView* touchedView = [touch view];
if([touchedView isKindOfClass:[UIButton class]]) {
return NO;
}
return YES;
}
This works in most cases. In addition you may want to check whether the touched view is a descendent of a the scroll view using isDescendantOfView:.
Hope it helps.
I think your answer is UIGestureRecognizerDelegate's method:
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
Check if the touch's view property is any of the UIButtons you are trying to avoid: if so return NO, otherwise return YES. Don't forget to assign the UITapGestureRecognizer's delegate so it works. Hope this helps.

UISegmentedControl not firing with iOS 5

Does anyone else see this issue? I am using a segmented control, and I've overridden it so that when the user hits the same segment(index), it is deselected.
This worked fine in previous versions, but now testing on iOS5. And I am finding that the UIControlEventValueChanged is not sent when you tap on the same segment. So the code works ok when you tap on different segments, but does not for the same segment.
My code.
segmentCtrl = [[MySegmentedControl alloc] initWithItems: segmentCtrlLabels];
segmentCtrl.segmentedControlStyle = UISegmentedControlStyleBar;
// Register for touch events
[segmentCtrl addTarget:self action:#selector(segmentedCtrlTouched:) forControlEvents:UIControlEventValueChanged];
I tried to register for UIControlEventTouchUpInside, and get the same behavior.
Any suggestions for work around?
Regards,
Yenyi
Fixed it by registrering for a touch event. If the touched segment is the same, I manually send the EventChanged event.
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
NSInteger current = self.selectedSegmentIndex;
[super touchesBegan:touches withEvent:event];
if (current == self.selectedSegmentIndex) {
[self setSelectedSegmentIndex:current];
[self sendActionsForControlEvents:UIControlEventValueChanged];
}
}
Yup you need to implement the control events yourself.
- (void) touchesBegan: (NSSet *) touches withEvent: (UIEvent *) event
{
[super touchesBegan: touches withEvent: event];
[self sendActionsForControlEvents: UIControlEventTouchDown];
}
- (void) touchesEnded: (NSSet *) touches withEvent: (UIEvent *) event
{
[super touchesEnded: touches withEvent: event)];
if (CGRectContainsPoint(self.bounds, [touches.anyObject locationInView: self]))
{
[self sendActionsForControlEvents: UIControlEventTouchUpInside];
}
else
{
[self sendActionsForControlEvents: UIControlEventTouchUpOutside];
}
}
- (void) touchesCancelled: (NSSet *) touches withEvent: (UIEvent *) event
{
[super touchesCancelled: touches withEvent: event];
[self sendActionsForControlEvents: UIControlEventTouchCancel];
}

How can I get touchesBegan event on SuperView

In my program there is two views(scrollView-super, view-sub*2).
In my case two subviews are subviewed in scrollView. touchesBegan event called in subviews.
How Can I get event in scrollView???
#interface MyScrollView:UIScrollView
...
#implement MyScrollView
...
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
//here is my code
//but I can't get event here
...
}
-(id)initWithFrame:(CGRect) frame
{
...
MyView *view1 = [[MyView alloc] initWithFrame:(0, 0, 320, 240);
MyView *view2 = [[Myview alloc] initWithFrame:(0, 240, 320,240);
[self addSubview: view1];
[self addSibvoew: view2];
...
}
#interface MyView:UIView
...
#implement MyScrollView
...
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
//break points
//here comes event
}
Try this code..
UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(singleTapGestureCaptured:)];
[scroll addGestureRecognizer:singleTap];
- (void)singleTapGestureCaptured:(UITapGestureRecognizer *)touch{
CGPoint touchPoint=[gesture locationInView:scrollView];
touchPoint = [touch locationInView:self.view];
}
I suggest making ur two subview global and then in the superview touchesbegan method pass the touches and the event to the subviews for handling. So somethig like [view1 touchesBegan:touches event:event];
i have not tested it but that should be one way.

Resign First Responder on ScrollView Touch

How can I hide the keyboard on ScrollView touch event...
Scenario is like that...
->View ->ScrollView ->Textfield
I want to hide the keyboard on touch of scrollView. I tried to override the class for scrollview but still i can't do it.
Doing like this will help:
#interface MyClass <UIScrollViewDelegate> {
}
#implementation
- (void)viewDidLoad {
yourScrollView.delegate = self;
}
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {
[myTextField resignFirstResponder];
}
If you really want to handle the touch event, then you need to subclass the UIScrollView and override the method:
- (BOOL)touchesShouldBegin:(NSSet *)touches withEvent:(UIEvent *)event inContentView:(UIView *)view {
}
More about UIScrollView touch
This is what worked for me
in your viewController's viewDidLoad-method
UITapGestureRecognizer *tapScroll = [[UITapGestureRecognizer alloc]initWithTarget:self action:#selector(tapped)];
tapScroll.cancelsTouchesInView = NO;
[viewScroller addGestureRecognizer:tapScroll];
where viewScroller is your scroller. In the tapped-method we have
- (void) tapped {
[self.view endEditing:YES];
}
Don't know why but the above did not work for me...even though it should
Try this:
Add gesturerecognizer for scrollview,
UITapGestureRecognizer *tapScroll = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(tapped)];
tapScroll.cancelsTouchesInView = NO;
[yourScrollview addGestureRecognizer:tapScroll];
[tapScroll release];
Resign your keyboard in (tapped:) method.
Please, take a look at this answer, This is the easiest one I found.
UitextField resignFirstResponder does not work in scroll view
- (BOOL)touchesShouldBegin:(NSSet *)touches withEvent:(UIEvent *)event inContentView:(UIView *)view
{
[self.view endEditing:YES];
return YES;
}