2009-05-30 3 views
0

Ich habe eine UIScrollView, wo viele Objekte (UIImageView) während des Scrollens angezeigt werden. Wenn der Benutzer jedoch scrollt, möchte ich Nachrichten an alle diese Objekte senden, um ihnen mitzuteilen, dass sie nichts Dummes tun sollen. Wenn UIScrollView verlangsamt wird, finden einige Animationen an den sichtbaren Objekten statt. Wenn der Benutzer schnell weiterfährt (pagingEnabled = YES), werden immer mehr Objekte animiert, was zu einer schrecklichen Scroll-Leistung führt.Was ist die einfachste und schnellste Art, 30 Objekte zur "gleichen" Zeit zu verschicken?

Ich möchte ihnen allen sagen, sofort zu stoppen und nichts zu tun, sobald der Benutzer scrollt. Was kann ich also tun? Eine For-Schleife ist schlecht für die Leistung beim Scrollen. Es wird für einen kleinen Moment zucken, aber das ist genug, um den Benutzer sehr sehr wütend zu machen.

Antwort

2

Denken Sie auch daran, dass die Computer nur Dinge in einer linearen Art und Weise tun können. Egal was Sie tun, Sie müssen eine Art Schleifenstruktur verwenden.

vielleicht starten Sie einen Thread, der die Schleife enthält. und die Schleife ruft den Selektor für jedes Objekt auf. (Sie erinnern sich für UI-Sachen hat es auf dem Haupt-Thread ausgeführt werden.)

und ich gehe davon aus Sie verwenden

+ (void)setAnimationsEnabled:(BOOL)enabled 

Um die Animation zu stoppen.

Wenn dies immer noch nicht schnell genug ist, müssen Sie auf Core Animationen schauen, diese werden zusätzliche Effizienz haben, um dies zu ermöglichen.

+0

Das ist eine süße Lösung. Das ist ungefähr so ​​nah wie "simultan" wie es wird. – Naren

4

Setzen Sie sie alle in ein Array und verwenden Sie [NSArray makeObjectsPerformSelector:]. Das ist die prägnanteste Art, es zu tun, aber ich bin mir nicht sicher, es ist effizienter als eine For-Schleife ...

Ich bin mir nicht sicher, wie Sie Ihre Ansichten animieren, aber Sie möchten vielleicht verwenden Die Delegiertenfunktionen von UIScrollView verwalten ein Subarray von sichtbaren Elementen und beschränken Ihre Animationen auf diese. Wenn sich beispielsweise das sichtbare Rechteck ändert, können Sie sich Ihre vorhandene Liste sichtbarer Ansichten ansehen und feststellen, ob sie vollständig außerhalb des Bildschirms liegen. Sie könnten aufhören, diese zu animieren. Sie können dann nach Ansichten suchen, die auf dem Bildschirm, aber nicht in der Liste waren, und Animationen auf ihnen beginnen. Ich habe so etwas schon einmal gemacht und es hat wesentlich dazu beigetragen, die Leistung zu verbessern!

Wenn Sie dann alle laufenden Animationen einfrieren möchten, haben Sie eine Reihe von animierenden Animationen und es ist relativ kurz.

Hoffe, dass hilft!

+0

-makeObjectsPerformSelector: wird eine for-Schleife intern verwenden und hat den Nachteil, dass die aufgerufene Methode keine Parameter übernehmen müssen. Ich mache schon etwas ähnliches, wo ich nur Animationen an den Objekten starte, die sich auf der aktuell sichtbaren Seite befinden. Das heißt, das Rechteck ist ein Vielfaches der Bildbreite von scrollView. Das Problem ist, wenn der Benutzer zu schnell vorgeht. Dann laufen alte Animationen noch, während neue starten. Meine Animationen werden komplexer, je mehr der Benutzer scrollView beschleunigt. Also summieren sich die Dinge schnell;) – Thanks

+0

Ich habe auch darüber nachgedacht, einfach alles anzuhalten, was außerhalb des Bildschirms ist, aber das Problem ist: Der Benutzer scrollt nach rechts, schnell zurück nach links. Und dann erwartet er/sie, dass Animationen immer noch "verlangsamen". Also muss ich einen Bereich von mindestens 0,5 Seiten um das Ansichtsfenster scrollView aktiv halten, aber alle Animationen außerhalb dieses Bereichs abbrechen. – Thanks

+0

Es gibt einen makeObjectsPerformSelector: withObject-Methode, wenn Sie Argumente liefern müssen – monowerker

1

Versuchen Sie, jede Nachricht in einem anderen Thread auszuführen. Natürlich müssen alle UI-Updates auf dem Hauptthread sein, aber wenn Sie etwas Arbeit in einem Hintergrundthread machen können, wird es vielleicht etwas Verzögerung reduzieren. (Ich kann nicht sagen, wie machbar das ist für 30+ Objekte jedoch)

Verwandte Themen