2010-12-13 68 views
8

我有一個UIScrollView,我已經設置爲一次刷一列(每頁兩列) - 通過將框架設置爲視圖實際寬度的一半,將clipToBounds設置爲NO並使用hitTest將框架外部的區域聲明爲屬於UIScrollView(請參見下面的示例)。
UIScrollview外部的剪輯邊界外的子視圖沒有收到觸摸

這很好,但我現在的問題是,UIScrollView的子視圖沒有得到任何觸摸事件 - 只有主UIScrollView。

在以下示例中,如果包含hitTest代碼,那麼scrollview會正確滾動,一次分頁一列,並且可能會看到其所有內容 - 但內部滾動視圖不會接收到觸摸事件。

如果我刪除hitTest代碼,那麼只有第一個子滾動視圖接收到觸摸,並且可以看到其所有內容 - 但主滾動視圖不會在非剪切區域中觸及。

我該如何解決這個問題?

例子:

//========================================= 
// 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 

更新
我獲得通過執行以下操作轉發到內部視圖中的接觸,但肯定必須有一個更好的辦法?

- (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]; 
    } 
} 
+0

我看到它與此類似(http://stackoverflow.com/questions/3735218/paging-uiscrollview-with-peeking-neighbor-pages),但問題依然存在。 – 2010-12-14 10:41:11

回答

10

這可能工作:

- (UIView*)hitTest:(CGPoint)point withEvent:(UIEvent*)event { 
    UIView* child = nil; 
    if ((child = [super hitTest:point withEvent:event]) == self) 
     return self.scrollView;   
    return child; 
} 

但是,如果子視圖是滾動型出來的邊界事件並沒有解僱,這個函數返回self.scrollView。

相關問題