2010-12-13 9 views
8

Ho un UIScrollView che ho impostato per scorrere una colonna alla volta (due colonne per pagina) - impostando il frame su metà della larghezza effettiva delle viste, impostando clipToBounds su NO e usa hitTest per dichiarare l'area esterna al frame come appartenente a UIScrollView (vedi esempio sotto).
UIScrollview subviews al di fuori dei limiti di ritaglio che non ricevono tocchi

Questo funziona benissimo, ma il mio problema ora è che le sottoview di UIScrollView non ottengono alcun evento di tocco: solo l'UIScrollView principale.

Nell'esempio seguente, se è incluso il codice hitTest, la visualizzazione a scorrimento scorre correttamente, è possibile visualizzare una colonna alla volta e tutto il suo contenuto può essere visualizzato, ma le visualizzazioni di scorrimento interne non ricevono gli eventi di tocco.

Se rimuovo il codice hitTest, solo il primo scrollview del bambino riceve i tocchi e tutto il suo contenuto può essere visto, ma la vista a scorrimento principale non avrà i tocchi nell'area non ritagliata.

Come posso risolvere questo?

Esempio:

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

Aggiornamento
ottengo i tocchi trasmessi alla visione interiore facendo quanto segue, ma sicuramente ci deve essere un modo migliore?

- (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

Vedo che è simile a questo (http://stackoverflow.com/questions/3735218/paging-uiscrollview-with-peeking-neighbor-pages) ma il problema rimane. –

risposta

10

Questo può funzionare:

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

Ma se visualizzazione secondaria è fuori ScrollView delimita eventi non sono stati licenziati e questa funzione restituisce self.scrollView.

Problemi correlati