Programmatically pass touches to UIScrollView to scroll - iphone

Basically I'm trying to make UIScrollView only scroll on higher angles. As in right now if you move your finger 10 degrees off horizontal, the scrollview will scroll. I'd like to push that up to, say, 30 degrees.
After doing some reading, I established the best way to do this would be to put a subclassed UIView on top of the scrollview. If the UIView on top's touches are above 30 degrees, pass it down to the scrollview, and otherwise don't.
However, I can't figure out how to pass the touches down. Here's my code right now:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
NSLog(#"glass touch began");
UITouch *touch = [touches anyObject];
beginning_touch_point = [touch locationInView:nil];
[scroll_view touchesBegan:touches withEvent:event];
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
NSLog(#"glass touch ended");
UITouch *touch = [touches anyObject];
CGPoint previous_point = beginning_touch_point;
CGPoint current_point = [touch locationInView:nil];
float x_change = fabs(previous_point.x - current_point.x);
float y_change = fabs(previous_point.y - current_point.y);
if(x_change > y_change)
{
if(previous_point.x - current_point.x < 0)
{
[(MyScheduleViewController *)schedule_controller didFlickLeft];
}
else
{
[(MyScheduleViewController *)schedule_controller didFlickRight];
}
[scroll_view touchesCancelled:touches withEvent:event];
}
else
{
[scroll_view touchesEnded:touches withEvent:event];
}
}
I know right now that it's checking for 45 degrees, but that's not the important thing. What is important is that the touches are indeed getting passed down correctly to my scroll_view. I have it doing a NSLog() on touchesbegan and touchesended, and it's doing both correctly. It's just not scrolling. I'm worried touchesBegan and touchesEnded cannot cause a scroll. Does anyone know what can, or what I'm doing wrong?

I also tried to do the same but didn't succeed. It seems scrollView doesn't handle touchesMoved/touchesBegan, but it handles some other events to understand that user wants to scroll the view.
For me the solution was to determine thet shift value and set it explicitly as a scrollView content offset. It looked like this (I don't have the exact source code no, this code may work incorrectly):
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
UITouch *touch = [touches anyObject];
CGPoint curr = [touch locationInView: self];
CGPoint offset = [scrollView contentOffset];
[scrollView setContentOffset: CGPointMake(offset.x + (curr.x - prev.x), offset.y) animated:YES];
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
prev = [[touches anyObject] previousLocationInView: self];
}

Related

touchesMoved reaching out of my view bounds

I have subclassed UIView and there initially my view will be in a default color and i need to fill some different color on touch (from x axis = 0 to user touched point),here the problem is touchesMoved even if i drag out of my self view bounds it is getting those points,how to restrict it to only for my self view bounds.
I googled & tried below snippets but of no luck
if([self pointInside:point withEvent:nil]){
[self fillColor];
}
My touchesMoved method is as below,
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
CGPoint point = [touch locationInView:self];
endPoint = point;
NSLog(#"moved x: %f,y: %f",point.x,point.y);
if(CGRectContainsPoint([self frame], endPoint)){ // this also not working
[self fillColor];
}
}
Any help is appreciated in advance.
just set tag in viewDidLoad: method and use bellow logic..
fillColorView.tag = 111;
and use bellow logic in touchesMoved: method like bellow..
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *tap = [touches anyObject];
CGPoint pointToMove = [tap locationInView:fillColorView];
if([tap.view isKindOfClass:[UIView class]])
{
UIView *tempView=(UIView *) tap.view;
if (tempView.tag == 111){
[self fillColor];
}
}
}
hope this help you...
In your touchesMoved method, CGPoint point = [touch locationInView:self]; replcae self by the view in which you wants the touch to be worked.
self will get the complete view, you should pass your drawingView at there, so that it will detetc touch only on that view.

With touches - how to stop UIIMageView moving when reaching a certain Y point

I have an image at the bottom of the screen.
I want the user to to move the image upwards until it reaches a certain Y point as follows:
[door setCenter:CGPointMake(160,347)];
So far, as you drag the image (door) upwards it continues past my destination point but when you let go it snaps back to the correct position.
How do I stop the image moving when reaching a certain point if the user's finger is still swiping upwards? Would it be inside an if statement?
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
if (startPoint.y < 347) {
// something in here ?????
}
}
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
UITouch *myTouch = [touches anyObject];
startPoint = [myTouch locationInView:self.view];
NSLog(#"position = %f and %f",startPoint.x,startPoint.y);
[door setCenter:CGPointMake(160, startPoint.y)];
}
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
[door setCenter:CGPointMake(160,347)];
}
How about setting it in touchesMoved method. Something like,
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
UITouch *myTouch = [touches anyObject];
startPoint = [myTouch locationInView:self.view];
NSLog(#"position = %f and %f",startPoint.x,startPoint.y);
if (startPoint.y < 347) { //or suitable condition to verify your case
[door setCenter:CGPointMake(160, startPoint.y)]; //then only set the center
} else
{
[door setCenter:CGPointMake(160,347);
}
}

Disable UIView on TouchesMoved

I have an application in which i have to move images, problem is arising when mouse touches the images it gets moved but if it touches the main View, whole view is also moving.
I tried view.userInteractionEnabled=NO;
but after one move whole view gets freeze.
I want my view to be static(not moving)
Help !!!
here is the code
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [[event allTouches] anyObject];
UIImageView *imgPimples = [[UIImageView alloc]init];
imgPimples = (UIImageView*)[touch view];
CGPoint touchLocation = [touch locationInView:imgPimples];
imgPimples.center = touchLocation;
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
}
Just check whether touched class is of kind UIImageView.
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [[event allTouches] anyObject];
if ([[touch view] isKindOfClass:[UIImageView class]]) {
UIImageView *imgPimple;
imgPimple = (UIImageView *)[touch view];
CGPoint touchLocation = [touch locationInView:imgPimple];
imgPimple.center = touchLocation;
}
}
I think it will serve your purpose.
if ([touch.view isKindOfClass:[UIImageView class]]){
imgPimples.center = touchLocation;
}
assuming your parent view is not also a UIImageView.

Pass on a Tap to an UITextView

I was wondering how to pass on a tap on an UIView to an UITextView. This is my code so far:
- (void)foundTap:(UITapGestureRecognizer *)recognizer {
label.text = #"Touch detected";
[self.view bringSubviewToFront:aTextView];
[aTextView touchesBegan:touches withEvent:event];
}
Now, this obviously does not work as touches and event are not defined. But how do I define them? I can't declare touches as 1 (won't work). I could initialise it like so:
UITouch *touches =[touches anyObject];
But then again, touches is still undeclared. And I have no idea of how to declare the event. This is usually easy if you use the - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {} method, but I want to pass on the tap not the touches. Any help would be very much appreciated.
Edit:
I rewrote the method, but I still can't pass on the tap to the UITextView. I now need to double tap in order to edit it, i.e. the first tap for bringing the aTextView upfront and the second tap will then edit the UITextView (as it is in front and thus receives all the touches swipes etc.):
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
[super touchesMoved:touches withEvent:event];
UITouch *touch = [touches anyObject];
CGPoint currentPosition = [touch locationInView:self.view];
CGFloat deltaX = fabsf(gestureStartPoint.x - currentPosition.x); // will always be positive
CGFloat deltaY = fabsf(gestureStartPoint.y - currentPosition.y); // will always be positive
if (deltaY == 0 && deltaX == 0) {
label.text = #"Touch"; [self performSelector:#selector(eraseText) withObject:nil afterDelay:2];
[self.view bringSubviewToFront:aTextView];
[self.view bringSubviewToFront:doneEdit];
[aTextView touchesBegan:touches withEvent:event];
}
}
See if this previous SO question iPhone: Detecting Tap in MKMapView helps you.

UIView movement

Which is the best way to move a UIView.
I have a custom UIView with some custom things in it, like shadows, labels etc.
Today I'm using, for move this UIView.:
- (void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [[event allTouches] anyObject];
if (self.isEditing) {
CGPoint location = [touch locationInView:[rootView view]];
self.center = location;
}
}
Is this the best way to move a UIView? I experience this a bit laggy.
I usually reposition a view using the offset between the touchesBegan location and the touchesMoves location.