2010-09-04 2 views
43

Ho riscontrato un piccolo problema nella mia app.UIButton touch è in ritardo quando in UIScrollView

Essenzialmente ho una serie di UIButtons aggiunto come subviews in un UIScrollView che fa parte di un pennino. Ogni volta che tocco un pulsante, si nota un ritardo notevole prima che il pulsante venga evidenziato. In pratica devo tenerlo premuto per circa mezzo secondo prima che il pulsante si attenui e appaia selezionato.

Suppongo che ciò sia dovuto al fatto che lo UIScrollView deve determinare se il tocco è una pergamena o se si tratta di un tocco destinato a una visualizzazione secondaria.

Ad ogni modo, sono un po 'incerto su come procedere. Voglio semplicemente che il pulsante appaia selezionato non appena lo tocco.

Qualsiasi aiuto è apprezzato!

Edit:

Ho provato a installare delaysContentTouches-NO ma lo scorrimento diventa quasi impossibile, poiché la maggior parte della mia ScrollView è pieno di UIButtons.

+0

consulta questo risposta invece di quella accettata: http://stackoverflow.com/a/19656611/378024 – galambalazs

risposta

39

Ok ho risolto questo sottoclassi UIScrollView e prioritario touchesShouldCancelInContentView

Ora la mia UIButton che è stato etichettato come 99 evidenzia correttamente e la mia ScrollView scorre!

myCustomScrollView.h:

@interface myCustomScrollView : UIScrollView { 

} 

@end 

e myCustomScrollView.m:

@implementation myCustomScrollView 

    - (BOOL)touchesShouldCancelInContentView:(UIView *)view 
    { 
     NSLog(@"touchesShouldCancelInContentView"); 

     if (view.tag == 99) 
      return NO; 
     else 
      return YES; 
    } 
+6

Wow, ho appena trovato questa risposta e ha risolto completamente il problema che stavo avendo. Vorrei poterti dare +1000 punti! Grazie mille. –

+0

non funziona nel mio caso, ma è molto vicino al tuo. (Testato solo nel simulatore). Forse questa soluzione è scaduta. –

+0

Versione Swift in basso, continua a leggere ... –

25

Provare a impostare la proprietà UIScrollView delaysContentTouches su NO.

+1

Mi dispiace, probabilmente avrei dovuto essere più chiaro. Se imposto delaysContentTouches su NO, il touch risponde immediatamente. Tuttavia, lo scorrimento praticamente diventa impossibile poiché i tocchi vengono interpretati come i pulsanti premuti anziché lo scorrimento effettivo. – Jeff

+0

@Jeff È possibile utilizzare 'canCancelContentTouches' per consentire lo scorrimento anche se il tocco viene inizialmente considerato come un tocco di pulsante, purché gli obiettivi di cancellazione del supporto tattile. I pulsanti saranno ancora evidenziati inizialmente quando viene toccato, ma non appena si inizia a scorrere non si evidenzia. – devios1

+0

@chaiguy Sto cercando questo comportamento, esattamente come hai descritto, ma finora non ho avuto fortuna. Se imposto 'delaysContentTouches = NO' e' canCancelContentTouches = YES' non riesco a scorrere quando tocchi UIButton. – Darrarski

0

Nessuna delle soluzioni esistenti ha funzionato per me. Forse la mia situazione è più unica.

Ho molti UIButtons all'interno di uno UIScrollView. Quando viene premuto UIButton, viene presentato un nuovo UIViewController all'utente. Se un pulsante viene premuto e tenuto premuto a lungo, il pulsante mostrerà il suo stato depresso. Il mio cliente si lamentava che se si batte troppo velocemente, non viene mostrato lo stato depresso.

La mia soluzione: All'interno del metodo UIButtons 'tap, dove mi carico la nuova UIViewController e presente sullo schermo, io uso

[self performSelector:@selector(loadNextScreenWithOptions:) 
      withObject:options 
      afterDelay:0.] 

Questo orari del carico del prossimo UIViewController sul prossimo ciclo di eventi. Tempo permettendo allo UIButton di ridisegnare. Lo UIButton ora mostra il suo stato di depressione prima di caricare il successivo UIViewController.

37

soluzione di Jeff non è stato del tutto lavorando per me, ma questo simile si fa: http://www.charlesharley.com/2013/programming/uibutton-in-uitableviewcell-has-no-highlight-state/

Non sono sicuro se questo è stato il caso per la risposta di Jeff, ma oltre a override -touchesShouldCancelInContentView: in vista di scorrimento sottoclasse, è ancora è necessario impostare delaysContentTouches su NO. Infine, anziché restituire NO per i pulsanti, è necessario restituire YES. Ecco un esempio dal link precedente.

- (instancetype)initWithFrame:(CGRect)frame { 
    if (self = [super initWithFrame:frame]) { 
     self.delaysContentTouches = NO; 
    } 

    return self; 
} 

- (BOOL)touchesShouldCancelInContentView:(UIView *)view { 
    if ([view isKindOfClass:UIButton.class]) { 
     return YES; 
    } 

    return [super touchesShouldCancelInContentView:view]; 
} 

Versione Swift.

override func touchesShouldCancelInContentView(view: UIView!) -> Bool { 
    if view is UIButton { 
     return true 
    } 
    return super.touchesShouldCancelInContentView(view) 
} 
+3

questo funziona per me e non la risposta accettata. Grazie. –

+3

Ottima soluzione! Se utilizzi il generatore di interfacce, seleziona la finestra di scorrimento e deseleziona "ritardi per i contenuti" nell'ispettore degli attributi. – Tim

+1

Lavora per me! Grazie. – frank

0

soluzione Storyboard: Selezionare la vista di scorrimento, aprire il "Attributi" e deselezionare "Ritardi Touches Contenuto"

enter image description here

0

Swift 3:

scrollView.delaysContentTouches = false 
1

In Swift 3 :

import UIKit 

class ScrollViewWithButtons: UIScrollView { 

    override init(frame: CGRect) { 
     super.init(frame: frame) 
     myInit() 
    } 

    required init?(coder aDecoder: NSCoder) { 
     super.init(coder: aDecoder) 
     myInit() 
    } 

    private func myInit() { 
     self.delaysContentTouches = false 
    } 

    override func touchesShouldCancel(in view: UIView) -> Bool { 
     if view is UIButton { 
      return true 
     } 
     return super.touchesShouldCancel(in: view) 
    } 
} 

È quindi possibile utilizzare questo ScrollViewWithButtons in IB o nel codice.