6

Ich habe eine Anforderung zum Erstellen eines Audio-Level-Visualizer mit einem benutzerdefinierten Muster. Ich habe das Bild als PNGs eingestellt. Mein aktueller Ansatz ist wie dieserUIImageView Animation basierend auf Lautstärke-Feedback

1)

2) Legen Sie das entsprechende Bild auf dem UIImageView auf der Grundlage der Lautstärke des Audiopegels des Mikrofons holen.

// audio level timer 
self.levelTimer = [NSTimer scheduledTimerWithTimeInterval: 0.001 target: self selector: @selector(levelTimerCallback:) userInfo: nil repeats: YES]; 

Image

- (void)levelTimerCallback:(NSTimer *)timer { 
[self.audioRecorder updateMeters]; 
const double ALPHA = 0.05; 
double peakPowerForChannel = pow(10, (0.05 * [self.audioRecorder peakPowerForChannel:0])); 
lowPassResults = ALPHA * peakPowerForChannel + (1.0 - ALPHA) * lowPassResults; 

//NSLog(@"Average input: %f Peak input: %f Low pass results: %f", [self.audioRecorder averagePowerForChannel:0], [self.audioRecorder peakPowerForChannel:0], lowPassResults); 

if (lowPassResults > 0.0 && lowPassResults <= 0.05){ 
    imgViewRecordAnimation.image = nil; 
    imgViewRecordAnimation.image = [UIImage imageNamed:@"anim1"]; 
} 
if (lowPassResults > 0.06 && lowPassResults <= 0.10){ 
    imgViewRecordAnimation.image = nil; 
    imgViewRecordAnimation.image = [UIImage imageNamed:@"anim2"]; 
} 
if (lowPassResults > 0.11 && lowPassResults <= 0.15){ 
    imgViewRecordAnimation.image = nil; 
    imgViewRecordAnimation.image = [UIImage imageNamed:@"anim3"]; 
} 
if (lowPassResults > 0.16 && lowPassResults <= 0.20){ 
    imgViewRecordAnimation.image = nil; 
    imgViewRecordAnimation.image = [UIImage imageNamed:@"anim4"]; 
} 
if (lowPassResults > 0.21 && lowPassResults <= 0.25){ 
    imgViewRecordAnimation.image = nil; 
    imgViewRecordAnimation.image = [UIImage imageNamed:@"anim5"]; 
} 
if (lowPassResults > 0.26 && lowPassResults <= 0.30){ 
    imgViewRecordAnimation.image = nil; 
    imgViewRecordAnimation.image = [UIImage imageNamed:@"anim6"]; 
} 
if (lowPassResults > 0.31 && lowPassResults <= 0.35){ 
    imgViewRecordAnimation.image = nil; 
    imgViewRecordAnimation.image = [UIImage imageNamed:@"anim7"]; 
} 
if (lowPassResults > 0.36 && lowPassResults <= 0.40){ 
    imgViewRecordAnimation.image = nil; 
    imgViewRecordAnimation.image = [UIImage imageNamed:@"anim8"]; 
} 
if (lowPassResults > 0.41 && lowPassResults <= 0.45){ 
    imgViewRecordAnimation.image = nil; 
    imgViewRecordAnimation.image = [UIImage imageNamed:@"anim9"]; 
} 
if (lowPassResults > 0.46 && lowPassResults <= 0.50){ 
    imgViewRecordAnimation.image = nil; 
    imgViewRecordAnimation.image = [UIImage imageNamed:@"anim10"]; 
} 
if (lowPassResults > 0.51 && lowPassResults <= 0.55){ 
    imgViewRecordAnimation.image = nil; 
    imgViewRecordAnimation.image = [UIImage imageNamed:@"anim11"]; 
} 
if (lowPassResults > 0.56 && lowPassResults <= 0.60){ 
    imgViewRecordAnimation.image = nil; 
    imgViewRecordAnimation.image = [UIImage imageNamed:@"anim12"]; 
} 
if (lowPassResults > 0.61 && lowPassResults <= 0.65){ 
    imgViewRecordAnimation.image = nil; 
    imgViewRecordAnimation.image = [UIImage imageNamed:@"anim13"]; 
} 
if (lowPassResults > 0.66 && lowPassResults <= 0.70){ 
    imgViewRecordAnimation.image = nil; 
    imgViewRecordAnimation.image = [UIImage imageNamed:@"anim14"]; 
} 
if (lowPassResults > 0.71 && lowPassResults <= 0.75){ 
    imgViewRecordAnimation.image = nil; 
    imgViewRecordAnimation.image = [UIImage imageNamed:@"anim15"]; 
} 
if (lowPassResults > 0.76 && lowPassResults <= 0.80){ 
    imgViewRecordAnimation.image = nil; 
    imgViewRecordAnimation.image = [UIImage imageNamed:@"anim16"]; 
} 
if (lowPassResults > 0.81 && lowPassResults <= 0.85){ 
    imgViewRecordAnimation.image = nil; 
    imgViewRecordAnimation.image = [UIImage imageNamed:@"anim17"]; 
} 
if (lowPassResults > 0.86 && lowPassResults <= 0.90){ 
    imgViewRecordAnimation.image = nil; 
    imgViewRecordAnimation.image = [UIImage imageNamed:@"anim18"]; 
} 
if (lowPassResults > 0.86){ 
    imgViewRecordAnimation.image = nil; 
    imgViewRecordAnimation.image = [UIImage imageNamed:@"anim19"]; 
} 

} 

Aber der Ausgang ist nicht glatt wie eine echte Visualizer Animation. Was sollte der beste Ansatz sein? Teilen Sie, es gibt bessere Möglichkeiten, dies zu tun.

Paar von Bildern

enter image description here

enter image description here

enter image description here

+0

Das klingt, als könnte es das gleiche wie dieses Problem sein: http://stackoverflow.com/questions/2834573/how-to-animate-the-change-of-image-in-a-uiimageview – dudeman

+0

Warum bist du Setzen Sie jedes Bild vor der Einstellung der image -Eigenschaft auf "nil" ('imgViewRecordAnimation.image = nil;')? – arturdev

Antwort

3

Wenn Sie glauben, ändert sich das Bild ruckelt sucht, sollten Sie besser anwenden Animationen auf sie. Übrigens müssen Sie nil nicht auf imgViewRecordAnimation.image setzen, da Sie danach alle richtigen Bilder einstellen, was zu unnötiger Verzögerung führt. Sie können auch alle if-Anweisungen zu else machen, wenn sonst alle if-Anweisungen ausgeführt werden.

Kommen Sie zur Lösung, können Sie einfach den Link folgen, der @MileAtNobel gepostet hat. Oder wenn Sie nicht viel Code ändern möchten, können Sie eine einfache Animation auf die Eigenschaft backgroundColor anwenden. Sie können den Timer auch entfernen, überprüfen Sie den folgenden Code und sehen Sie, ob der Code gut funktioniert. Ich habe auch versucht, den Code mit großer Ähnlichkeit zu optimieren, ich hoffe, dass dies die Performance verbessert.

BOOL flagToContinue ; //assign NO to this flag to stop updating the images 

-(void)levelTimerCallback 
{ 
    NSLog(@"Volume Logic Begins") ;//Volume level logic begins 
    [self.audioRecorder updateMeters]; 
    const double ALPHA = 0.05; 
    double peakPowerForChannel = pow(10, (0.05 * [self.audioRecorder peakPowerForChannel:0])); 
    lowPassResults = ALPHA * peakPowerForChannel + (1.0 - ALPHA) * lowPassResults ; 
    NSLog(@"Volume Logic ends") ;//Volume level logic ends 

    [UIView animateWithDuration:0.001f 
       delay:0.0f 
      options: UIViewAnimationOptionCurveLinear 
     animations:^{ 
      mgViewRecordAnimation.backgroundColor = [UIColor colorWithPatternImage:[NSString stringWithFormat:@"anim%d", (int)ceil(lowPassResults * 20)]]; 
     } 
     completion:^(BOOL finished) { 
      if(finished && flagToContinue) [self levelTimerCallback]; 
    }]; 
} 
+0

Danke für die Antwort, Aber immer noch gleich, nicht so glatt wie normale Bildanimation – sajaz

+0

In diesem Fall sollten Sie sehen, wie viel Zeit es dauert, um die Lautstärke zu ermitteln. Nehmen Sie Zeitstempel vor dem Start und nach dem Ende (wie in meinem Code erwähnt) und sehen Sie den Zeitunterschied, ich denke, dass Ihre Volumenlogik mehr Zeit braucht, deshalb sind die Animationen nicht glatt. – Trident

2

Ok, ich gebe Ihnen keine direkte Lösung, sondern versuche eine Lösung vorzuschlagen, die Sie ausprobieren müssen. Schreiben Sie stattdessen ein benutzerdefiniertes Steuerelement, anstatt das Image von imageView zu ändern. Erstellen Sie eine Unterklasse einer Sicht. Überschreiben Sie die DrawRect-Methode. Sie können entweder das erforderliche Muster abhängig vom Steuerwert zeichnen oder das Bild selbst zeichnen. Aber der erste Ansatz wird empfohlen. Benutzerdefinierte Zeichnung ist im Vergleich zum Ändern des Bildes glatt. Bitte probieren Sie es aus und lassen Sie mich wissen, dass es funktioniert.