On Jun 9, 2011, at 5:23 PM, Roland King wrote:

> 
> On 10-Jun-2011, at 12:44 AM, Matt Neuburg wrote:
> 
>> On Wed, 01 Jun 2011 22:25:32 +0800, Roland King <[email protected]> said:
>>> I've been taking advantage of the fact that UIView's don't clip to their 
>>> bounds by making my superview of size CGSizeZero and adding content to it. 
>>> This means I can position the whole view hierarchy using its center, which 
>>> is always at (0,0). This is very useful as my view has subviews which move 
>>> all over the place and I really only care about the top left, the superview 
>>> is just a convenient canvas to hang them on. 
>>> 
>>> I got bitten by that today however because none of my subviews get touches, 
>>> I believe that's because a touch outside the superview bounds is ignored, 
>>> the views are shown, they aren't clipped, but the touches are 'clipped'. 
>>> 
>>> Is there method call to tell a view to hitTest: out of its own bounds, just 
>>> considering the subviews? 
>> 
>> See chapter 18 of my book. Basically, your assessment is exactly right; all 
>> you have to know is how hit-testing works. You touch outside your view, so 
>> as the hit-test percolates down through the views it comes to your view and 
>> asks: was this touch inside you? And your view says no, rightly, and that's 
>> the end of that; we never get down to your view's subviews.
>> 
>> So clearly all you have to do is modify hit-testing, which is easy: your 
>> view must test its subviews even if the touch is outside itself. Something 
>> like this, in your UIView (largely off the top of my head, but this should 
>> work to get you started):
>> 
>> -(UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
>>   UIView* result = [super hitTest:point withEvent:event];
>>   if (result)
>>       return result;
>>   for (UIView* sub in [self.subviews reverseObjectEnumerator]) {
>>       CGPoint pt = [self convertPoint:point toView:sub];
>>       result = [sub hitTest:pt withEvent:event];
>>       if (result)
>>           return result;
>>   }
>>   return nil;
>> }
>> 
> 
> that's just about exactly what I ended up with .. thanks! 
> 
> -(UIView*)hitTest:(CGPoint)point withEvent:(UIEvent *)event
> {
>        UIView *retval = nil;
>        // traverse the subviews in backwards order until one returns something
>        for( UIView *subview in [ [ self subviews ] reverseObjectEnumerator ] )
>                if( ( retval = [ subview hitTest:[ subview convertPoint:point 
> fromView:self ] withEvent:event ] ) )
>                        break;
> 
>        return retval;
> }
> 

Yup, yours looks great. You do some things I'd never do but they're purely 
stylistic, I think. And you can afford to throw caution to the winds because 
you know you *never* want to return yourself.

m.

_______________________________________________

Cocoa-dev mailing list ([email protected])

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to [email protected]

Reply via email to