2013-02-11 7 views
5

Devo ricevere una notifica quando termina il trascinamento di UITableView.Come rilevare l'evento di fine trascinamento di un UITableView?

Ma sto lavorando su una categoria di UITableView, quindi non posso usare scrollViewDidEndDragging:willDecelerate: per archiviarlo.

ho cercato uso KVO di osservare il dragging Percorso chiave:

[self addObserver:self forKeyPath:@"dragging" options:NSKeyValueObservingOptionNew context:nil]; 

Ma observeValueForKeyPath:ofObject:change:context: non ha ottenuto chiamati, poiché UITableView.dragging non ha e setter e questa proprietà non è compatibile con KVO.

C'è qualche altro metodo per archiviare questo aspetto per l'utilizzo di scrollViewDidEndDragging:willDecelerate:?

Qualsiasi aiuto è grato! Grazie!

risposta

8

Edit: La mia soluzione qui di seguito è stata la prima cosa a venire in mente e si è rivelata piuttosto hacky e può essere pericoloso da utilizzare nel caso in cui Apple decide di cambiare la struttura interna di classe UIScrollView. Vedi lo answer suggerito da Mazyod che dovrebbe essere più sicuro e più diretto.


Questo dipende dall'implementazione e può essere modificato da Apple nei futuri aggiornamenti iOS, ma attualmente UIScrollView classe sembra basarsi su sistemi di riconoscimento dei gesti per la gestione di interazione con l'utente e UITableView essere una sottoclasse della classe di visualizzazione di scorrimento fa lo stesso .

Se si va al UIScrollView.h del quadro UIKit, è possibile notare un sospetto _pan ivar che ha un tipo di id, ma sembra essere in realtà un UIPanGestureRecognizer.

Quindi ho provato questo, e sembra funzionare.

[_tableView addObserver: self 
       forKeyPath: @"pan.state" 
       options: NSKeyValueObservingOptionNew 
       context: nil]; 

Quando si trascina la visualizzazione della tabella, state del riconoscitore gesto cambia più volte, e quando si smette di trascinamento, state riceve la sua ultima modifica al valore del UIGestureRecognizerStateEnded.

Si prega di notare che anche se questo sembra fare il trucco, qualche altro problema potrebbe ostacolarlo. In genere non è una buona idea sovrascrivere i metodi di classe esistenti in una categoria poiché l'implementazione originale diventa inaccessibile dopo di ciò. Documentazione sul protocollo informale NSKeyValueObserving afferma che

NSObject fornisce un'implementazione del protocollo NSKeyValueObserving che fornisce una capacità di osservazione automatico per tutti gli oggetti.

Quindi, se si ignora observeValueForKeyPath:ofObject:change:context: in una categoria, l'implementazione di default sarà inaccessibile (e non possiamo essere sicuri che UITableView o UIScrollView no KVO utente per qualcosa). Ciò potrebbe causare alcuni errori imprevisti.

+0

Come se implemento 'observValueForKeyPath: ofObject: change: context:' in alcuni Class 'Foo' e la categoria UITableView mantiene un'istanza di Foo? – OpenThread

+0

Grazie per l'aiuto! la tua risposta è molto utile per me! – OpenThread

+1

Implementazione di 'observValueForKeyPath: ofObject: change: context:' in una classe Foo separata dovrebbe in effetti aiutare con il problema "sovrascrivere il metodo esistente in una categoria". –

8

La risposta di Egor Chiglintsev mi ha ricordato che posso osservare la proprietà panGestureRecognizer già esposta nello UIScrollView. Dovrebbe essere molto più sicuro di pan. Ma poi .. ho scoperto che posso solo aggiungermi come bersaglio!

[_scrollView.panGestureRecognizer addTarget:self action:@selector(gestureRecognizerUpdate:)]; 

Questo funziona perfettamente per me!

+1

Immagino che sia il modo corretto in cui dovrebbe essere fatto. Non so perché le prime cose che mi vengono in mente sono di solito qualche runtime o hack relativi al KVO. Grazie) –

Problemi correlati