I have a UIScrollView that I configured to scroll one column at a time (two columns per page) - setting the border to half the actual width of the views, setting clipToBounds to NO and using hitTest to declare the area outside the frame belonging to UIScrollView (see example below).
This works fine, but now my problem is that touch events are not triggered in the UIScrollView subtitles - only the main UIScrollView.
In the following example, if hitTest
code is hitTest
, then scrolling is viewed correctly, swapping one column at a time and all its contents can be seen, but internal scrolling views do not receive touch events.
If I delete the hitTest
code, then only the first child scrollview will receive touches, and all its contents can be seen - but the main scrollview will not touch in the area without cropping.
How can i solve this?
Example:
//========================================= // UIScrollViewEx // Just in order to log touches... //========================================= @interface UIScrollViewEx : UIScrollView {} @end @implementation UIScrollViewEx - (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { NSLog(@"Touches Began (0x%08X)", (unsigned int)self); } @end //========================================= // UIViewEx // Dummy class - sets subview as hit target // just to demonstrate usage of non-clipped // content //========================================= @interface UIViewEx : UIView {} @end @implementation UIViewEx - (UIView *) hitTest:(CGPoint) point withEvent:(UIEvent *)event { if ([self pointInside:point withEvent:event]) { return [self.subviews objectAtIndex:0]; } return nil; } @end //========================================= // MainClass // Any UIViewEx based class which returns // the UIScrollView child on hittest //========================================= @implementation MyClass - (UIColor*) randomColor { int r = arc4random() % 100; int g = arc4random() % 100; int b = arc4random() % 100; return [UIColor colorWithRed:(0.01 * r) green:(0.01 * g) blue:(0.01 * b) alpha:1.0]; } - (void) loadScrollviews { // Set frame to half of actual width so that paging will swipe half a page only CGRect frame = CGRectMake(0, 0, self.bounds.size.width / 2, 400); // Main scrollview UIScrollView *scrollview = [[UIScrollView alloc] initWithFrame:frame]; [scrollview setBackgroundColor:[UIColor greenColor]]; [scrollview setPagingEnabled:YES]; [scrollview setClipsToBounds:NO]; // Create smaller scrollviews inside it - each one half a screen wide const int numItems = 5; for(int i = 0; i < numItems; ++i) { frame.origin.x = frame.size.width * i; UIScrollView *innerScrollview = [[UIScrollViewEx alloc] initWithFrame:frame]; [innerScrollview setContentSize:CGSizeMake(frame.size.width, 1000)]; [innerScrollview setBackgroundColor:[self randomColor]]; [scrollview addSubview:innerScrollview]; [innerScrollview release]; } [scrollview setContentSize:CGSizeMake(numItems * frame.size.width, frame.size.height)]; [self addSubview:scrollview]; } @end
Update
I get touches on the inside by doing the following, but surely there should be a better way?
- (UIView *) hitTest: (CGPoint) pt withEvent: (UIEvent *) event { if(CGRectContainsPoint(self.bounds, pt)) { UIScrollView *scrollview = [self.subviews objectAtIndex:0]; CGPoint scrollViewpoint = [scrollview convertPoint:pt fromView:self]; for(UIView *view in scrollview.subviews) { if(CGRectContainsPoint(view.frame, scrollViewpoint)) { return view; } } return scrollview; } else { return [super hitTest:pt withEvent:event]; } }
iphone ipad uiscrollview
Lk.
source share