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]
