2013-11-01 9 views
7

Ho qualche problema con l'inoltro di gesti e tocchi. Ci ho giocato un po ', ma non riesco a farlo funzionare come voglio io.Tocca in avanti e gesti alle visualizzazioni da UIScrollview

Fondamentalmente voglio controllare una scrollview su un dualscreen con 2 dita e inoltrare tutto il resto alle viste ipad dietro a una scrollview sovrapposta.

Per essere in grado di controllare la visualizzazione a scorrimento sul doppio schermo ho suddiviso le sottoclassi UIScrollView e l'ho aggiunto come visualizzazione sovrapposta a uno sfondo chiaro sullo schermo ipad.

Quindi l'ho collegato con un delegato per inoltrare il suo trascinamento e roba alla visualizzazione a scorrimento sul doppio schermo. questo funziona perfettamente.

Come ho scritto voglio lo ScrollView di rispondere solo a 2 finger-scroll, così ho impostato a

ScrollView.panGestureRecognizer.minimumNumberOfTouches = 2; 

Ma la ScrollView mangia tutti i tocchi e io non farlo bene di trasmettere tutto il resto, ma 2 dita toccano le viste dietro. Penso che l'override del

- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event 

deve fare il trucco, ma non farlo bene per rilevare il numero delle dita sullo schermo a destra.

risposta

4

Mi piacerebbe condividere/spiegare la soluzione al problema. Detto questo, voglio anche sottolineare che l'input del cappello mi ha portato nella giusta direzione. grazie mille, amico!

Il problema quando si tenta di inserire una vista/vista di scorrimento come un toplay di sovrapposizione è che il toplayer non conosce il suo "prossimo risponditore". mettendo la vista/vista a scorrimento come una vista sottostante si risolverà questo problema. potrebbe essere necessario per mettere a punto il comportamento tocco di qualsiasi ScrollView all'interno di tale ScrollView underlaying per ottenere il giusto comportamento (come impostare il numero massimo di tocchi)

La soluzione è quella di creare una sottoclasse un UIScrollView, ignorare questo metodi override the touchesBegan: and other touch methods as follows (vedi user1085093 risposta), e aggiungilo come vista sottostante alla schermata ipad.

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{ 

// If not dragging, send event to next responder 
if (!self.dragging){ 
    [self.nextResponder touchesBegan: touches withEvent:event]; 
} 
else{ 
    [super touchesBegan: touches withEvent: event]; 
}} 

-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{ 

// If not dragging, send event to next responder 
if (!self.dragging){ 
    [self.nextResponder touchesMoved: touches withEvent:event]; 
} 
else{ 
    [super touchesMoved: touches withEvent: event]; 
}} 


-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{ 

// If not dragging, send event to next responder 
if (!self.dragging){ 
    [self.nextResponder touchesEnded: touches withEvent:event]; 
} 
else{ 
    [super touchesEnded: touches withEvent: event]; 
}} 

ho fatto la messa a punto del ScrollView in questo modo:

TopLayerScrollView *newScrollView = [[TopLayerScrollView alloc] init]; 
[newScrollView setBackgroundColor:[UIColor clearColor]]; 
[newScrollView setFrame:self.tabBarController.view.frame]; 
[newScrollView setContentSize:dualScreenViewController.scrollContent.contentSize]; 
newScrollView.showsHorizontalScrollIndicator = NO; 
newScrollView.showsVerticalScrollIndicator = NO; 
newScrollView.delegate = self; 
newScrollView.bounces = NO; 
[newScrollView scrollsToTop]; 
newScrollView.panGestureRecognizer.minimumNumberOfTouches = 2; 

self.topLayerScrollView = newScrollView; 
[newScrollView release]; 

[self.tabBarController.view removeFromSuperview]; 
[topLayerScrollView addSubview:self.tabBarController.view]; 
[window addSubview:topLayerScrollView]; 
[topLayerScrollView bringSubviewToFront:self.tabBarController.view]; 

Il metodo delegato del ScrollView underlaying:

- (void)scrollViewDidScroll:(UIScrollView *)scrollView{ 
if (scrollView.dragging || scrollView.tracking) 
{ 
    [dualScreenViewControlleremphasized text.scrollContent setContentOffset:CGPointMake(scrollView.contentOffset.x, scrollView.contentOffset.y) animated:NO]; 
    self.tabBarController.view.frame = CGRectMake(scrollView.contentOffset.x, scrollView.contentOffset.y, self.tabBarController.view.frame.size.width, self.tabBarController.view.frame.size.height); 
}} 

Questa soluzione funziona alla grande. L'altra soluzione sarebbe quella di avere una vista a scorrimento come una vista sovrapposta come inizialmente intendevo. Come detto, il problema è lasciare che la vista del toplayer sia a conoscenza delle viste (nextResponder). Per ottenere questo risultato, è necessario sublocare UIScrollview e creare una proprietà UIResponder da collegare nel file di interfaccia utente o durante il runtime. in questo modo lo scrollview sovrapposto saprà chi è il prossimo risponditore. please see morningstar's answer

2

Sfortunatamente, non è possibile fare nulla con -pointInside:withEvent: qui perché il sistema decide in quale vista è toccato il tocco (o in cui sono visualizzati i tocchi) prima che determini se soddisfano i requisiti del riconoscitore di gesti.

Penso che la soluzione migliore qui sia avere la vista che attualmente è dietro la scrollview in realtà la vista del contenuto della scrollview e spostare quella vista ogni volta che l'offset del contenuto della vista di scorrimento cambia per mantenerlo nel stessa posizione sullo schermo. (Sembra costoso ma non lo è davvero.) Quindi, invece di essere una sovrapposizione, la vista di scorrimento è più simile a un sottopunto.

Si può anche giocare con UIScrollView.delaysContentTouches, -[UIScrollView touchesShouldBegin:withEvent:inContentView:], ecc. Per perfezionare il comportamento.

+0

grazie mille per questo. Ho aggiunto una spiegazione su come ho risolto questo alla fine. – Tom

1

aggiornamento per Xcode 6.4, Swift 1.2:

Ho anche una sottoclasse UIScrollView:

import UIKit 

class WBMScrollView: UIScrollView 
{ 
    override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) 
    { 
     self.nextResponder()?.touchesBegan(touches, withEvent: event) 
     super.touchesBegan(touches, withEvent: event) 
    } 
} 

Nell'applicazione vc principale ViewController.swift ho provato in:

override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) { 
     println(" touches began") 
    } 

e lavorato. La scrollview è stata aggiunta tramite IB e collegata a ViewController.swift

0

Con la mia app mi servivano gli eventi di tocco con un dito per essere inoltrati al controllore di visualizzazione genitore della vista di scorrimento pur consentendo la visualizzazione di scorrimento per ingrandire/ridurre .

L'utilizzo del prossimo risponditore non ha funzionato perché sto aggiungendo anche un'altra vista sovrapposta che finisce per diventare il prossimo risponditore e rubare gli eventi di tocco. Ho finito per fare qualcosa in base alla risposta di Tom semplicemente passando il controllore della vista genitore e inviando direttamente gli eventi touch. Eccolo in Swift:

class CustomScrollView: UIScrollView { 

    var parentViewController: UIViewController? 

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { 
     parentViewController?.touchesBegan(touches, with: event) 
    } 

    override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) { 
     parentViewController?.touchesMoved(touches, with: event) 
    } 

    override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) { 
     parentViewController?.touchesEnded(touches, with: event) 
    } 
} 
Problemi correlati