2010-11-05 15 views
17

Ho un elemento dell'interfaccia utente di una circonferenza che viene aggiornato da un NSTimer. Ho anche un UIScrollView che "blocca" il cerchio rotante mentre viene fatto scorrere. Era previsto, perché il timer e la vista di scorrimento erano entrambi nello stesso thread.I miei elementi dell'interfaccia utente personalizzati non vengono aggiornati mentre scorre UIScrollView

Quindi ho inserito il timer in una discussione separata che funziona in modo ottimale! Posso vederlo funzionare perché gli NSLogs continuano a venire anche mentre scorrono.

Ma il mio problema è che il mio cerchio rotante si ferma ancora a scorrere! Sospetto che il ridisegno sia interrotto fino alla successiva iterazione del ciclo di esecuzione del thread principale (?). Quindi, anche se il suo angolo è cambiato continuamente, potrebbe non essere ridisegnato ...

Qualche idea cosa posso fare? Grazie!

risposta

42

Durante lo scorrimento, il ciclo di esecuzione del thread principale è UITrackingRunLoopMode. Quindi quello che devi fare è programmare il tuo timer in quella modalità (possibilmente in aggiunta alla modalità predefinita). Credo NSRunLoopCommonModes comprende sia la modalità di monitoraggio degli eventi di default e, quindi si può solo fare questo:

NSTimer *timer = [NSTimer timerWithTimeInterval:0.42 target:foo selector:@selector(doSomething) userInfo:nil repeats:YES]; 
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes]; 

A proposito, si dovrebbe fare tutto questo sul thread principale. Non è necessario generare un thread in background (a meno che ogni richiamo del timer non esegua una lunga elaborazione).

+0

+1, funziona alla grande per me. – pt2ph8

+0

Hai ragione, NSRunLoopCommonModes è la modalità corretta per questo, grazie! Mi sono liberato del thread in background e il timer si attiva ora, anche durante lo scorrimento.Ma il mio problema è ancora lì, non avviene il ridisegno. – Sebastian

+0

Che cosa stai facendo per avviare il ridisegno? Penserei che un "setNeedsDisplay" farà il trucco. Forse dovresti pubblicare il tuo metodo di timer. –

0

È corretto che UIScrollView non aggiorna la visualizzazione del contenuto durante lo scorrimento.

Probabilmente la soluzione migliore - e questa è una specie di trucco - è visualizzare la vista di animazione separatamente (magari all'interno di una vista di fotogramma, per ottenere il ritaglio gratuito) e utilizzare i callback del delegato della vista di scorrimento per trovare fuori la posizione corrente della pergamena e posizionare l'animazione di conseguenza.

NOTA: questo suggerimento è un hack! Non sono le migliori pratiche e sicuramente è contrario a un codice semplice e manutenibile senza effetti collaterali. Tuttavia, è l'unico modo in cui posso pensare di ottenere il display che desideri.

Un'altra virata: ripensare all'importanza di visualizzare i contenuti animati di una vista a scorrimento mentre scorre.

+0

No, il cerchio animato non fa parte del contenuto della vista di scorrimento! Scusate, forse non ero chiaro su questo. – Sebastian

3

UIScrollView non solo blocca NSTimers, ma blocca l'intero thread principale. E gli oggetti UIKit dovrebbero essere accessibili solo sul thread principale (e, spesso, sono limitati in modi imprevedibili se si tenta di evitare questa restrizione), il che probabilmente è il motivo: anche se si ha un orologio proveniente da un thread esterno - si non è in grado di pubblicare aggiornamenti.

È un po 'schivo, ma c'è un modo per realizzare l'animazione con CoreAnimation? Le cose legate continuano a funzionare indipendentemente da ciò che sta accadendo nel thread principale.

+0

Bene, il timer non è bloccato affatto. Ce l'ho in esecuzione sul thread principale in NSRunLoopCommonModes ora e si attiva anche durante lo scorrimento. Ma la mia vista non viene ridisegnata, almeno non attraverso il meccanismo setNeedsDisplay/display di UIView. I documenti dicono: "Qualsiasi oggetto UIView contrassegnato come necessario alla visualizzazione viene automaticamente visualizzato di nuovo quando l'applicazione ritorna al ciclo di esecuzione." – Sebastian

+0

CA è una grande idea, ci proverò! – Sebastian

Problemi correlati