If there is a uiscrollview and and multiple sub view on the uiscrollview. how to know where the user touches i.e on specific view or scrollview(blank space)
Use this approach:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
NSLog(#"View touched: %#", touch.view);
}
This method is called every time your finger touches the screen, and the touch knows which view it touched.
Edit: It won't work on a UIScrollView because the scroll view gets the touch itself, check this:
touchesBegan method not called when scrolling in UIScrollView
How to enable touch began in UIScrollView?
You have 2 possibilities for detect the touch with - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event; in a scrollView:
first, implement this method in your viewController, and add the scrollview on this viewController.
second, which I recommend: make a custom class which is inherited from UIScrollView like this:
.h:
#interface CustomScrollView : UIScrollView
#end
.m:
#import "CustomScrollView.h"
#implementation CustomScrollView
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
[self.nextResponder touchesBegan:touches withEvent:event];
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
if(!self.dragging){
[self.nextResponder touchesMoved:touches withEvent:event];
}
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
[self.nextResponder touchesEnded:touches withEvent:event];
}
#end
in your vc make:
...
CustomScrollView* customScrollView = [[CustomScrollView alloc]initWithFrame:CGRectMake(0, 0, 320, 480)];
...
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
NSLog(#"View touched: %#", touch.view);
}
Related
I try a lot methods but not get solution
In my case, my view hierarchy:
UIView
UIScrollView
LeftContainer + RightContainer
(in RihgtContainer) ViewContainer
TableView
I tried these:
subclassing Scrollview and
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
[self.nextResponder touchesBegan:touches withEvent:event];
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
if(!self.dragging)
{
[self.nextResponder touchesMoved:touches withEvent:event];
}
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
[self.nextResponder touchesEnded:touches withEvent:event];
}
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
innerTableView.scrollEnabled = YES;
innerTableView.alwaysBounceVertical = NO;
You can tray to set the delaysTouchesBegan to true on your scrollview... like here https://stackoverflow.com/a/31040918/1702413
but ..
UITableview is inherited from UIScrollView
You should not embed UIWebView or UITableView objects in UIScrollView objects https://stackoverflow.com/a/17121582/1702413
i have a uiwebview and an uiview next to each other everone taking 50% of the screen width.
i can smoothly scroll the uiwebview - and i want to be able that if i scroll up/down on the uiview - that the uiwebview scrolls in the given direction.
already subclassed uiview - and trie'd to send the touchesEnded... events to the webview.scrollview.
.h
#interface UIViewScrollDispatcher : UIView
#property(nonatomic, assign) id scroller;
.m
#implementation UIViewScrollDispatcher
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {
[self.scroller touchesCancelled:touches withEvent:event];
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
[self.scroller touchesEnded:touches withEvent:event];
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
[self.scroller touchesBegan:touches withEvent:event];
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
NSLog(#"TOUCHHHH %#", self.scroller);
[self.scroller touchesMoved:touches withEvent:event];
}
using it like this:
UIViewScrollDispatcher * rightarea = [[UIViewScrollDispatcher alloc] initWithFrame:CGRectMake(0, 0, 300, 300)];
rightarea.backgroundColor=[UIColor redColor];
rightarea.scroller=self.webView.scrollView;
tried it with self.webView and self.webView.scrollView
doesn't work - any help?
btw: the NSLog inside the touchesMoved gets called
regards
ok - did it with uiscrollview subclass and sync the .contentOffset and .contentSize
I need to use touch events but i am trying to detect it from another class, so i will call back to my main class if touched or moved etc.
I am calling init method in "classTouchEvents" firstly from my main class like that
objectTouchEvents=[[classTouchEvents alloc]initWith:self.view];
here is initWith method of "classTouchEvents"
- (id)initWith:(UIView *)selfView
{
self = [super init];
if (self) {
NSLog(#"here");
view=[[UIView alloc]init];
view=selfView;
// Custom initialization
}
return self;
}
and i get "here" log so i guess it is working but i cant detect if view get touch or anything. Here is my touch events in classTouchEvents
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
NSLog(#"touchBegan");
}
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
NSLog(#"touchMoved");
}
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
NSLog(#"touchEnded");
}
But i cant get any log about touches. I need some help.
Thanks in advance.
I'd use delegation:
TouchDelegate.h:
#import <UIKit/UIKit.h>
#protocol TouchDelegate <NSObject>
#optional
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event;
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event;
#end
And then in your view (that actually receives the touch event), create a touchDelegate property (or just delegate if there is unlikely to be others):
#import "TouchDelegate.h"
#interface MyView : UIView
#property (weak, nonatomic) id<TouchDelegate> touchDelegate;
...
#end
and then delegate as normal:
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
if ([_touchDelegate respondsToSelector:#selector(touchesBegan:withEvent:)]) {
[_touchDelegate touchesBegain:touches withEvent:event];
}
}
// etc.
I would implement a custom subclass of UIView with a delegate.
#protocol TouchEventsDelegate <NSObject>
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event inView:(UIView *)view;
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event inView:(UIView *)view;
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event inView:(UIView *)view;
#end
#property (weak, nonatomic) id<TouchEventsDelegate> delegate;
Implement these delegate methods in your ClassTouchEvents.
Implement the touch events method in your custom view and call the delegate.
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
if (self.delegate && [self.delegate respondsToSelector:#selector(touchesBegan:withEventinView)]) {
[self.delegate touchesBegan:touches withEvent:event inView:self];
}
}
I've an UITextView into an UITableViewCell, but I can't scroll the text. When I try to scroll the textView, the tableView catch the touches.
There is any way to fix this?
PS: Subclass of UITableViewController
I'm thinking you can detect the object being touched and if it is a UITextView, then temporarily disable scrolling with UITableView:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
[super touchesBegan:touches withEvent:event];
UITouch *touch = [touches anyObject];
//detect if touch is on UITextView
if ([touch.view isKindOfClass: UITextView.class]) {
yourTableView.scrollEnabled = NO;
}
}
Don't forget to re-enable scrolling of the UITableView afterwards in touchesEnded
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
yourTableView.scrollEnabled = YES;
}
I have a UITableView as a subview in the UIViewController's view. I understand that I can detect the touch event by overwritting
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
[super touchesBegan:touches withEvent:event];
}
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
[super touchesEnded:touches withEvent:event];
}
-(void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
{
[super touchesCancelled:touches withEvent:event];
}
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
[super touchesMoved:touches withEvent:event];
}
But it never detected these events in the ViewController if I touched the tableview. As suggested in this forum by others, I should had a custom UITableView and added the above lines in it. I did that, but still the viewController did not detect the touch event. Any suggestions? Thanks.
After a few days of Googling, I finally found the solution that works for me. The key is to pass the responder chain to the next responder. For instance, in the touch began case, add the following line.
[self.nextResponder touchesBegan:touches withEvent:event]