Frage

habe ich ein UIView mit einem Bündel von Subviews, alle positioniert mit layoutSubviews. Wenn die view Größe verändert wird, positioniert die relativ alle ändern. Ich möchte diese Neuberechnungen während eines animierten Resize (mit + [UIView beginAnimations:] Anrufe) geschehen. Dies scheint nicht zu passieren. Irgendwelche Ideen?

War es hilfreich?

Lösung

Annahme: Sie möchten mehrere Animationsschritte haben (das heißt Position mit Rahmengröße nicht linear ändern)

.

Dies ist nicht möglich, mit einer einzigen „Standard“ UIView Animationen. Warum? Die Rahmen / Grenzen werden nur gesetzt, einmal.

Core Animation drei "Schicht Bäume" hat:

  • Das Modellbaum ist, wo Ihre App denkt die Dinge sind.
  • Die Präsentation Baum ist ungefähr das, was auf dem Bildschirm angezeigt ist wird.
  • Die Rendering-Struktur ist ungefähr das, was Core Animation ist Compositing.

UIView ist ein (etwas dünn) Wrapper um die Modellschicht. Während einer UIView Animation, aktualisiert Core Animation der Präsentation / Baum machen - das Modellbaum stellt den Endpunkt der Animationen. Das Ergebnis ist, dass der Code kann (zum größten Teil) treat Animationen als momentaner - eine Ansicht von A nach B zu bewegen sofort geht es weiter zu B; die Veränderung geschieht nur an den Benutzer animiert werden.

Es gibt mehr komplizierte Dinge, die Sie direkt mit CALayer / CAAnimation tun können, aber ich habe nicht untersucht, so viel.

Sie können Kette mehrere Animationen zusammen mit - [UIView setAnimationDidStopSelector:]. (Sie können auch mehrere Animationen zusammen mit setAnimationDelay versuchen, mit :, aber ich bin nicht sicher, was mit mehreren Animationen auf dem gleichen Grundstück geschieht, man Glück mit setAnimationBeginsFromCurrentState haben könnte.)

Wenn Sie wirklich wollen, eine feinkörnige Steuerung, CADisplayLink (OS 3.1+) ist ein Timer, der ausgelöst wird nach jeder Aktualisierung des Bildschirms. Eine Ersatzoption (für 3.0-Unterstützung) ist eine NSTimer bei 30/60 Hz oder so zu verwenden.

Andere Tipps

Die Komponenten @ GrizzlyNetch des anwer, können Sie die UIViewAnimationOptionLayoutSubviews Animation Option gesetzt, so dass Sie Anruf layoutIfNeeded nicht brauchen:

-(void)someMethod{
    double duration = ...;
    [UIView animateWithDuration:duration delay:0 options:UIViewAnimationOptionLayoutSubviews animations:^{
        self.frame = ...;
    } completion:nil];
}

Ich weiß, das ist eine alte Frage, aber dieser Code funktioniert sehr gut für mich (geeignet für Ihr Beispiel Rahmen zu ändern).

-(void)layoutSubviews{
     [super layoutSubviews];
     // layout your subviews here, or whatever
}

-(void)someMethod{
    double duration=...;
    [UIView animateWithDuration:duration animations:^{
        self.frame = ...;
        [self layoutIfNeeded];
    }];
}

Natürlich können Sie diese Methode von einem anderen Objekt aufrufen. Der „Trick“ ist layoutIfNeeded zu nennen (oder layoutSubviews direkt - Gleiche, wenn Sie den Rahmen ändern die setNeedsLayout genannt wird).

Wie tc. schön erklärt die „Schicht Bäume“, Sie nur die Präsentationsschicht zwingen, mit Animation die letzte Phase der Modellschicht angezeigt werden soll.

Der Vorteil dieses Verfahrens Möglichkeit ist, zu steuern, wenn der Rahmen / begrenzeÄnderung animiert wird und wenn es Instant.

Hope, das hilft jemand.)

Posting auf Vollständigkeit. Dank tc. zu erklären, was ich tun will, genau, von Core Animation wird nicht unterstützt.

Ich kam schließlich mit einer angemessenen Lösung auf. Vielmehr dann meine Subviews Layout in -layoutSubviews, das tue ich so in -setBounds :. Dann, wenn ich einen -setBounds wickeln: Anruf in einem UIView + beginAnimations: Block, werden diese Positionierung Anrufe auch animiert, und das Endergebnis ist alles richtig belebend, wo es sein sollte Gott.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top