2009-04-15 16 views
0

Ich erstelle eine einfache Farbauswahl, die von einem benutzerdefinierten Schieberegler gesteuert wird.Wie optimierst du UIColor auf dem iPhone?

Ich übermittle einen Gleitkommawert von meinem Schieberegler an eine UIColor-Konstruktormethode und aktualisiere die Hintergrundfarbe eines CALayers, wenn sich der Wert ändert.

Es läuft sehr flüssig im Simulator, aber ich bekomme eine Menge Flimmern beim Laufen auf dem Gerät.

Ist das nur, weil es die GPU überfordert? Es ist seltsamerweise das Schlimmste, wenn man sich durch Blau bewegt. Und das Ändern des Alpha-Wertes und der Helligkeit flimmert mehr als das Ändern der Sättigung und des Farbtons.

Sollte ich keine Gleitkommawerte übergeben, wenn sich der Wert des Schiebereglers ändert? Wenn nicht, wie könnte ich dies auf weniger Farben für die Optimierung beschränken?

Ich dachte, implizite Animationen für die backgroundColor-Eigenschaft des CALayer deaktivieren, aber ich bin mir nicht sicher, wie dies zu tun ist.

Gibt es Tricks zur Optimierung von UIColor-Änderungen?

aktualisieren

Ich verwende drawRect nicht: oder drawInRect:

ich die Backgroundcolor-Eigenschaft eines CALayer bin nur zu ändern. Jedes Mal, wenn touchesMoved: aufgerufen wird, schnappe ich mir den Ort, erstelle einen float-Wert von 0.0 bis 1.0 und übergebe meinem Delegaten eine Nachricht, dass sich der Wert geändert hat, und rufe die - (void) updateCurrentColor-Methode auf.

Hier ist ein Beispiel für meine Implementierung:

@implementation MyCustomSliderView 


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

    hueLocation = [[touches anyObject] locationInView:self]; 

    //Smoothing 
    if ((hueLocation.x > previousHueLocation.x) && ((hueLocation.x - previousHueLocation.x) > 1.0) && (hueLocation.x - previousHueLocation.x) < 10.0) { 
     hueLocation.x = previousHueLocation.x + 1.0; 
    } 

    if ((hueLocation.x < previousHueLocation.x) && ((previousHueLocation.x - hueLocation.x) > 1.0) && (previousHueLocation.x - hueLocation.x) < 10.0) { 
     hueLocation.x = previousHueLocation.x - 1.0; 
    } 

    //Percentage of screen. 
    hueValue = hueLocation.x/self.bounds.size.width; 

    //Clip to 1.0 & 0.0 
    if (hueValue > 1.0) { 
     hueValue = 1.0; 
    } 
    if (hueValue < 0.0) { 
     hueValue = 0.0; 
    } 

    NSLog(@"Value is: %f", hueValue); 
    NSLog(@"Location %f", hueLocation.x); 

    previousHueLocation = hueLocation; 

    if([delegate respondsToSelector:@selector(updateCurrentColor)]) { 
     [delegate updateCurrentColor]; 
    } 

} 


@implementation MyViewController 

- (void)updateCurrentColor { 

    currentColor = [UIColor colorWithHue:hueSliderView.hueValue 
           saturation:saturationSliderView.saturationValue 
           brightness:brightnessSliderView.brightnessValue 
            alpha:alphaSliderView.alphaValue]; 

    colorLayer.backgroundColor = currentColor.CGColor; 

} 

Zuerst dachte ich, dass es Werte aufgrund der Ungenauigkeit der Touch-Oberfläche zu springen. Die Glättungsfunktion hat geholfen, aber es flackert immer noch etwas, besonders mit dem Alpha-Wert, auch wenn sich mein Standort nur um 1 Pixel ändert. Sollte ich dies auf eine begrenzte Anzahl von Farben/Werten beschränken, anstatt nur einen beliebigen Float zu übergeben? Auch das läuft super im Simulator, scheint nur ein Performance-Problem zu sein.

+0

Beschreiben Sie den Effekt, den Sie erhalten. Gibt es sichtbare vertikale/horizontale "Balken", an denen die Änderung sichtbar ist? Verschwinden Elemente vorübergehend? Erhalten Sie eine sichtbare, aber unerwünschte Übergangsfarbe? – Artelius

+0

Keine Balken. Die Farbe flackert hell und dunkel, wenn ich die Werte (Farbton, Sättigung, Helligkeit, Alpha) ändere. Wenn ich wirklich langsam gehe, ist es besser, aber manchmal flimmert es trotzdem. Ich habe die Methode touchesMoved so angepasst, dass nur ein Pixel nach dem anderen bewegt wurde, es sei denn, es wurde über 15 verschoben. Das half. Flackert trotzdem. –

Antwort

2

Durch das Deaktivieren impliziter Animationen wurde das Flackern beseitigt.

Ich habe die Farbe wechselnden Methoden aktualisiert, so dass die Hintergrundfarbe kann, wenn sie von touchesBegan genannt animiert werden :, aber nicht implizit animiert, wenn sie von touchesMoved genannt:

- (void)updateCurrentColorAnimated:(BOOL)animated { 

    currentColor = [UIColor colorWithHue:hueSliderView.hueValue 
           saturation:colorView.saturationValue 
           brightness:colorView.brightnessValue 
            alpha:alphaSlider.alphaValue]; 
    if (animated) { 

     colorLayer.backgroundColor = currentColor.CGColor; 

    } 

    if (!animated) { 

     [CATransaction begin]; 

     [CATransaction setValue:(id)kCFBooleanTrue 
         forKey:kCATransactionDisableActions]; 


     colorLayer.backgroundColor = currentColor.CGColor; 

     [CATransaction commit]; 

    } 

} 

Der Grund, warum ich meine eigenen Schieber gerollt so dass ich zu neuen Werten springen kann, anstatt den kleinen Schieberegler perfekt zu fangen, dessen Zusammenspiel ich nicht sehr gut fand.

1

Zeichnung auf dem iPhone ist doppelt gepuffert. Wenn Sie flackern, liegt das daran, dass Sie eine Sache zeichnen und dann eine andere - es ist nicht wegen Geschwindigkeitsproblemen.

Ich würde vermuten, Sie machen eine der folgenden Fehler:

  • Ihren Farbwert aktualisiert und aus Synchronisierung Ihres Farbquadrat-Zeichnung (so dass die Farbe nicht korrekt eingestellt ist, wenn Sie :) DrawInRect
  • andernfalls zu initialisieren/berechnen Sie die Farbe richtig
  • Löschen oder Nachziehen Rechtecks ​​(so Sie ungültige Farben angezeigt wird), wenn Sie sollten nicht

Eine andere Sache zu check ... Farben in Cocoa sind Float-Werte von Null bis 1. Die Einstellung ganzer Werte von 0 bis 255 (wie im Web oder Windows) führt zu ernsthaften Problemen. Wenn Ihre Farbberechnungen zwischen 0 und 255 liegen, dividieren Sie vor der Einstellung von UIColor durch 255.0.

+0

Was bedeutet "doppelt gepuffert" in diesem Zusammenhang? – erikprice

+0

@Matt Gallagher, danke, gerade aktualisierte Frage mit meiner Implementierung. –

+0

@erikprice "doppelt gepuffert" bedeutet, dass die gesamte Zeichnung außerhalb des Bildschirms erfolgt und dann nach Abschluss der Zeichnung auf dem Bildschirm kopiert wird. Dies bedeutet, dass ein Löschen auf Weiß, gefolgt von Farbschwarz, kein Flackern auf dem Bildschirm verursacht, da der weiße Zustand niemals angezeigt wird. –