Getting a subview Reference from TouchesMoved - ios

I have a 2d-Grid of subviews. As I drag my finger along these subviews I want to call discrete method's per view such that for each view I hover above this method is called once. Logging out the results of the touches parameter it seems that only one view is referenced through the drag, namely the one that touchesbegan was on top of. How do I get the view for where my finger is currently dragging based on coordinates?

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [[event allTouches] anyObject];
CGPoint touchLocation = [touch locationInView:self.contentView];
for (UIView *view in self.contentView.subviews)
{
if ([view isKindOfClass:[MyView class]] &&
CGRectContainsPoint(view.frame, touchLocation))
{
}
}
}
Ref: iOS - Detecting touches in a UIView?

Related

pointInside:withEvent inside uibezierpath (overlapping area between two views)

no matter how much I tried I couldn't have access (Handle scrolling/Touchevents) to the overlapping area (right triangle) between two square shaped views A and B (A in on top of B)as shown in this image
I want the right part (triangle B) with is defined by UIbezierpath to handle the scrolling for the view beneath it(which is B). I couldn't have access to it by pointInside: withEvent: since its a bezierpath.
Even touchesBegan:withEvent: didn't work at all
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
CGPoint touchPoint = [touch locationInView:self.view];
if ([leftPath containsPoint:touchPoint])
{ //Do something
}
}
Please help.
You have to implement hitTest method of UIView to detect touch on particular view. Simply subclass your View and implement hitTest method.
-(UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event{
if ([path containsPoint:point]){
return [super hitTest:point withEvent:event];
}
else{
return nil;
}
}

Send Gesture to the UIView behind (both should handle touch)

In my app I have an UIView on top of UISplitViewController (used "addSubView"). What I wanna do is to let the UIView handle the touch and then redirect it to the parent view so it could also handle it.
I think i have a work around for what you try to do. You'll have to subclass your topView and implement the following two methods:
The first method will handle your touch for the buttomView
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
CGPoint bottomViewHit = [bottomView convertPoint:point fromView:self];
if ([topView pointInside:topViewHit withEvent:event]) {
//manage your bottomView touch here..
return bottomView;
}
return [super hitTest:point withEvent:event];
}
The second method will handle the topView
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
CGPoint location = [touch locationInView:touch.view];
// manage your touch for topView here...
[view touchesBegan:touches withEvent:event];
}

Drag an image when touched on the object itself

I created a very simple app that contains a draggable UIImageView but I faced a problem that the image can be dragged without touching it. I'm sure that the hole issue is from anyObject but I have no idea how to replace it I tried self.view.image but it failed. So here's my code
-(void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [[event allTouches] anyObject];
CGPoint location = [touch locationInView:touch.view];
lineView.center = location;
}
-(void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
[self touchesBegan:touches withEvent:event];
}
any ideas?
Consider using a pan gesture recogniser. Add it only to the image view (and enable user interaction on the view). Now you will only get action method callbacks from the gesture when the view has actually been touched, your code becomes simpler, and you can move the view with that position.
Also, in your current code, it's weird to call touchesBegan: from touchesMoved:. If you keep that code (because you don't want to use a gesture), you should refactor the code that moves the view out into a different method and have both touchesBegan: and touchesMoved: call that method.
Try the following
-(void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [[event allTouches] anyObject];
CGPoint location = [touch locationInView:touch.view];
if ([lineView pointInside:location withEvent:event])
lineView.center = location;
}

iOS - Detecting touches in a UIView?

So I have a Subclass of UIView that is suppose to detect touches. The view detect touches only if the touches started inside the current view. When the touches start outside of the view and they move inside my custom view touchesMoved doesn't get called. Any solution to detect moving touches that have not started in the current view?
#implementation MycustomView
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
// This only gets called if touches have started in the current View
}
#end
The following solution worked. I have multiple instances of MyCustomView; as the touches move I want to detect the views that are being touched
I ended up moving touch detection from MyCustomView to its superView, so the following code is no longer in MyCustomView class:
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [[event allTouches] anyObject];
CGPoint touchLocation = [touch locationInView:self.contentView];
for (UIView *view in self.contentView.subviews)
{
if ([view isKindOfClass:[MyCustomView class]] &&
CGRectContainsPoint(view.frame, touchLocation))
{
}
}
}
this should fix it:
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [[event allTouches] anyObject];
for (UIView* subView in self.subviews)
{
if([subView pointInside:[self convertPoint:touch toView:subView] withEvent:event])
{
//do your code here
}
}
}
One way to do it (though there might be others) is to disable user interaction for the subviews and make their parent view track the movement (use the hitTest method to figure out which view the touch is currently over).
Try this....
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
for(UITouch *touch in touches)
{
CGPoint touchPointFirstBtn = [touch locationInView:self.ChordView];
if(CGRectContainsPoint(_btnC.frame, touchPointFirstBtn))
{
if (!_btnC.isHighlighted)
{
if(!Boolean)
{
title = #"C";
[_tlbView reloadData];
NSLog(#"%#",#"touches C");
}
[_btnC setHighlighted:YES];
Boolean = YES;
}
}
else
{
[_btnC setHighlighted:NO];
Boolean = NO;
}
}

Move a UIView with my finger

I'm trying to move a UIView (let's call it viewA), which is located on top of another UIView (let's call it viewB). viewB has the size of the iPad screen, and view A is much much smaller.
I manage to move things, but the whole screen moves (viewA + viewB), not only viewA.
Here is my code for viewA class:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [[event allTouches] anyObject];
CGPoint touchLocation = [touch locationInView:self->view];
if (CGRectContainsPoint(self.window.frame, touchLocation)) {
dragging = YES;
oldY = touchLocation.y;
}
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [[event allTouches] anyObject];
CGPoint touchLocation = [touch locationInView:self->view];
if (dragging) {
CGRect frame = self.window.frame;
frame.origin.y = self.window.frame.origin.y + touchLocation.y - oldY;
self.window.frame = frame;
}
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
dragging = NO;
}
What I do not understand, is that, I implemented these methods in the viewA class. "Self" should concern this viewA, right? So why does the whole page move when my finger move on the screen?
You are moving the entire window, which contains all the views, you should only move the view you want, viewA in your case.

Resources