How to change a UITouch's location before pass

2019-08-10 19:55发布

问题:

I have a parent UIView and a child UIView, I wanna let a touch pass through from child to parent, and handled by the two views.

y--------------
| parent      |
|   x------   |
|   |child|   |
|   |_____|   |
|_____________|

So in the child view, I override:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    // child touch handle 
    // ...
    // parent touch handle
    [self.nextResponder touchesBegan:touches withEvent:event];
}
but when I touch the `x` in child, it forwarded to `y` in parent (relative to the parent). I wanna a pass through effect (`x` in child, pass through to `x` in parent), so I need to change the touches' position before forwarding, right? How should I do this?

Thanks @Fogmeister. And that's it.

The UITouch can now pass to parent. And in the parent's touchesBegan, call

[touch locationInView:self]

to get the touch location.

回答1:

TL:DR

Don't make any conversions, just use the locationInView: method.

Long version

For this you can just use the code locationInView: like this...

UITouch *touch = [touches anyObject]; //assuming there is just one touch.

CGPoint touchPoint = [touch locationInView:someView];

This will convert the screen coordinate of the touch to a coordinate in the view you pass in.

i.e. if the user taps the point (10, 10) in the child view and then you pass it through to the next responder i.e. the parent. When you run [touch locationInView:parentView] you will get a point something like (60, 60) (taking rough guesses from your diagram).

UITouch Docs for locationInView

locationInView: Returns the current location of the receiver in the coordinate system of the given view.

-(CGPoint)locationInView:(UIView *)view

Parameters

view

The view object in whose coordinate system you want the touch located. A custom view that is handling the touch may specify self to get the touch location in its own coordinate system. Pass nil to get the touch location in the window’s coordinates.

Return Value

A point specifying the location of the receiver in view.

Discussion

This method returns the current location of a UITouch object in the coordinate system of the specified view. Because the touch object might have been forwarded to a view from another view, this method performs any necessary conversion of the touch location to the coordinate system of the specified view.

EXAMPLE

You have a view called parentView frame (0, 0, 320, 480) i.e. the whole screen. This has a subView called childView frame (50, 50, 100, 100).

In the childView

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    UITouch *touch = [touches anyObject];

    CGPoint touchLocation = [touch locationInView:self];

    NSLog(@"Child touch point = (%f, %f).", touchLocation.x, touchLocation.y);

    [self.nextResponder touchesBegan:touches withEvent:event];
}

In the parentView

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    UITouch *touch = [touches anyObject];

    CGPoint touchLocation = [touch locationInView:self];

    NSLog(@"Parent touch point = (%f, %f).", touchLocation.x, touchLocation.y);
}

*Now...

The user presses the screen in the exact center of the child view.

The output of the program will be...

Child touch point = (50, 50). //i.e. this is the center of the child view relative to the **child view**.
Parent touch point = (150, 150). //i.e. this is the center of the child view relative to the **parent view**.

I have done no conversion at all. The method locationInView does all this for you. I think you are trying to over complicate it.



标签: ios uiview