it-swarm.com.de

Wie animiere ich Bedingungsänderungen?

Ich aktualisiere eine alte App mit AdBannerView, und wenn keine Anzeige vorhanden ist, wird sie vom Bildschirm verschoben. Wenn es eine Anzeige gibt, wird sie auf dem Bildschirm angezeigt. Grundlegendes Zeug.

Im alten Stil habe ich den Frame in einen Animationsblock gesetzt. Neuer Stil, ich habe eine IBOutlet für die Auto-Layout-Einschränkung, die die Y-Position bestimmt, in diesem Fall den Abstand vom unteren Rand der Übersicht, und ändere die Konstante:

- (void)moveBannerOffScreen {
    [UIView animateWithDuration:5 animations:^{
        _addBannerDistanceFromBottomConstraint.constant = -32;
    }];
    bannerIsVisible = FALSE;
}

- (void)moveBannerOnScreen {
    [UIView animateWithDuration:5 animations:^{
        _addBannerDistanceFromBottomConstraint.constant = 0;
    }];
    bannerIsVisible = TRUE;
}

Und das Banner bewegt sich genau wie erwartet, aber keine Animation.

UPDATE: Ich habe es mir noch einmal angeschaut WWDC 12 - Best Practices für die Beherrschung des automatischen Layouts welches die Animation abdeckt. Es wird erläutert, wie Einschränkungen mit CoreAnimation aktualisiert werden:

Ich habe es mit dem folgenden Code versucht, erhalte aber genau die gleichen Ergebnisse:

- (void)moveBannerOffScreen {
    _addBannerDistanceFromBottomConstraint.constant = -32;
    [UIView animateWithDuration:2 animations:^{
        [self.view setNeedsLayout];
    }];
    bannerIsVisible = FALSE;
}

- (void)moveBannerOnScreen {
    _addBannerDistanceFromBottomConstraint.constant = 0;
    [UIView animateWithDuration:2 animations:^{
        [self.view setNeedsLayout];
    }];
    bannerIsVisible = TRUE;
}

Nebenbei habe ich mehrfach nachgesehen und dies wird auf dem Haupt-Thread ausgeführt.

919
DBD

Zwei wichtige Hinweise:

  1. Sie müssen layoutIfNeeded innerhalb des Animationsblocks aufrufen. Apple empfiehlt, es einmal vor dem Animationsblock aufzurufen, um sicherzustellen, dass alle ausstehenden Layoutvorgänge abgeschlossen wurden

  2. Sie müssen es speziell für die übergeordnete Ansicht (z. B. self.view) aufrufen, nicht für die untergeordnete Ansicht, mit der die Einschränkungen verknüpft sind. Dadurch werden alle eingeschränkte Ansichten aktualisiert, einschließlich der Animation anderer Ansichten, die möglicherweise auf die Ansicht beschränkt sind, deren Einschränkung Sie geändert haben (z. B. Ansicht B ist am unteren Rand von Ansicht A angefügt und Sie haben gerade die Ansicht A geändert) oben versetzt und Sie möchten Ansicht B damit animieren)

Versuche dies:

Ziel-C

- (void)moveBannerOffScreen {
    [self.view layoutIfNeeded];

    [UIView animateWithDuration:5
        animations:^{
            self._addBannerDistanceFromBottomConstraint.constant = -32;
            [self.view layoutIfNeeded]; // Called on parent view
        }];
    bannerIsVisible = FALSE;
}

- (void)moveBannerOnScreen { 
    [self.view layoutIfNeeded];

    [UIView animateWithDuration:5
        animations:^{
            self._addBannerDistanceFromBottomConstraint.constant = 0;
            [self.view layoutIfNeeded]; // Called on parent view
        }];
    bannerIsVisible = TRUE;
}

Swift

UIView.animate(withDuration: 5) {
    self._addBannerDistanceFromBottomConstraint.constant = 0
    self.view.layoutIfNeeded()
}
1630
g3rv4

Ich weiß die Antwort zu schätzen, aber ich denke, es wäre schön, etwas weiter zu gehen.

Die grundlegende Blockanimation aus der Dokumentation

[containerView layoutIfNeeded]; // Ensures that all pending layout operations have been completed
[UIView animateWithDuration:1.0 animations:^{
     // Make all constraint changes here
     [containerView layoutIfNeeded]; // Forces the layout of the subtree animation block and then captures all of the frame changes
}];

aber das ist wirklich ein sehr vereinfachtes Szenario. Was ist, wenn ich Unteransichtsbeschränkungen mit der updateConstraints -Methode animieren möchte?

Ein Animationsblock, der die Methode subviews updateConstraints aufruft

[self.view layoutIfNeeded];
[self.subView setNeedsUpdateConstraints];
[self.subView updateConstraintsIfNeeded];
[UIView animateWithDuration:1.0f delay:0.0f options:UIViewAnimationOptionLayoutSubviews animations:^{
    [self.view layoutIfNeeded];
} completion:nil];

Die updateConstraints-Methode wird in der UIView-Unterklasse überschrieben und muss am Ende der Methode super aufrufen.

- (void)updateConstraints
{
    // Update some constraints

    [super updateConstraints];
}

The AutoLayout Guide lässt zu wünschen übrig, ist aber lesenswert. Ich selbst benutze dies als Teil einer UISwitch, die eine Unteransicht mit einem Paar UITextField mit einer einfachen und subtilen Zusammenbruchanimation (0,2 Sekunden lang) umschaltet. Die Einschränkungen für die Unteransicht werden in den Methoden updateConstraints der UIView-Unterklassen wie oben beschrieben behandelt.

106

Im Allgemeinen müssen Sie nur die Einschränkungen aktualisieren und layoutIfNeeded im Animationsblock aufrufen. Dies kann entweder das Ändern der .constant -Eigenschaft eines NSLayoutConstraint, das Hinzufügen von Einschränkungen (iOS 7) oder das Ändern der .active -Eigenschaft von Einschränkungen (iOS 8 und 9) sein.

Beispielcode:

[UIView animateWithDuration:0.3 animations:^{
    // Move to right
    self.leadingConstraint.active = false;
    self.trailingConstraint.active = true;

    // Move to bottom
    self.topConstraint.active = false;
    self.bottomConstraint.active = true;

    // Make the animation happen
    [self.view setNeedsLayout];
    [self.view layoutIfNeeded];
}];

Beispielsetup:

Xcode Project so sample animation project.

Kontroverse

Es gibt einige Fragen, ob die Einschränkung geändert werden soll vor dem Animationsblock oder innerhalb it (siehe vorherige Antworten).

Das Folgende ist ein Twitter-Gespräch zwischen Martin Pilkington, der iOS unterrichtet, und Ken Ferry, der Auto Layout geschrieben hat. Ken erklärt, dass das Ändern von Konstanten außerhalb des Animationsblocks kann derzeit ​​funktionieren, aber nicht sicher ist und dass sie wirklich geändert werden sollten inside = der Animationsblock. https://Twitter.com/kongtomorrow/status/440627401018466305

Animation:

Beispielprojekt

Hier ist ein einfaches Projekt, das zeigt, wie eine Ansicht animiert werden kann. Es verwendet Objective C und animiert die Ansicht durch Ändern der .active -Eigenschaft mehrerer Einschränkungen. https://github.com/shepting/SampleAutoLayoutAnimation

67
Steven Hepting
// Step 1, update your constraint
self.myOutletToConstraint.constant = 50; // New height (for example)

// Step 2, trigger animation
[UIView animateWithDuration:2.0 animations:^{

    // Step 3, call layoutIfNeeded on your animated view's parent
    [self.view layoutIfNeeded];
}];
34
John Erck

Swift 4 Lösung

IView.animate

Drei einfache Schritte:

  1. Ändern Sie die Einschränkungen, z.

    heightAnchor.constant = 50
    
  2. Sagen Sie dem enthaltenen view, dass sein Layout verschmutzt ist und dass das Autolayout das Layout neu berechnen soll:

    self.view.setNeedsLayout()
    
  3. Im Animationsblock weisen Sie das Layout an, das Layout neu zu berechnen. Dies entspricht dem direkten Festlegen der Frames (in diesem Fall werden die Frames durch das automatische Layout festgelegt):

    UIView.animate(withDuration: 0.5) {
        self.view.layoutIfNeeded()
    }
    

Komplettes einfachstes Beispiel:

heightAnchor.constant = 50
self.view.setNeedsLayout()
UIView.animate(withDuration: 0.5) {
    self.view.layoutIfNeeded()
}

Nebenbemerkung

Es gibt einen optionalen 0. Schritt - bevor Sie die Einschränkungen ändern, können Sie self.view.layoutIfNeeded() aufrufen, um sicherzustellen, dass der Startpunkt für die Animation aus dem Zustand stammt, in dem alte Einschränkungen angewendet wurden (falls sich einige andere Einschränkungen geändert haben sollten) nicht in der Animation enthalten sein):

otherConstraint.constant = 30
// this will make sure that otherConstraint won't be animated but will take effect immediately
self.view.layoutIfNeeded()

heightAnchor.constant = 50
self.view.setNeedsLayout()
UIView.animate(withDuration: 0.5) {
    self.view.layoutIfNeeded()
}

IViewPropertyAnimator

Da wir mit iOS 10 einen neuen Animationsmechanismus haben - UIViewPropertyAnimator, sollten wir wissen, dass im Grunde derselbe Mechanismus für ihn gilt. Die Schritte sind grundsätzlich gleich:

heightAnchor.constant = 50
self.view.setNeedsLayout()
let animator = UIViewPropertyAnimator(duration: 0.5, timingParameters: UICubicTimingParameters(animationCurve: .linear))
animator.addAnimations {
    self.view.layoutIfNeeded()
}
animator.startAnimation()

Da animator eine Kapselung der Animation ist, können wir auf sie verweisen und sie später aufrufen. Da wir im Animationsblock nur das automatische Layout anweisen, die Frames neu zu berechnen, müssen wir die Einschränkungen ändern, bevor wir startAnimation aufrufen. Daher ist so etwas möglich:

// prepare the animator first and keep a reference to it
let animator = UIViewPropertyAnimator(duration: 0.5, timingParameters: UICubicTimingParameters(animationCurve: .linear))
animator.addAnimations {
    self.view.layoutIfNeeded()
}

// at some other point in time we change the constraints and call the animator
heightAnchor.constant = 50
self.view.setNeedsLayout()
animator.startAnimation()

Die Reihenfolge, in der Abhängigkeiten geändert und ein Animator gestartet werden, ist wichtig. Wenn Sie lediglich die Abhängigkeiten ändern und den Animator für einen späteren Zeitpunkt verlassen, kann der nächste Neuzeichnungszyklus eine automatische Neuberechnung des Layouts aufrufen und die Änderung wird nicht animiert.

Denken Sie auch daran, dass ein einzelner Animator nicht wiederverwendbar ist. Wenn Sie ihn einmal ausgeführt haben, können Sie ihn nicht erneut ausführen. Es gibt also wohl keinen guten Grund, den Animator in der Nähe zu halten, es sei denn, wir verwenden ihn zur Steuerung einer interaktiven Animation.

22
Milan Nosáľ

Storyboard, Code, Tipps und ein paar Fallstricke

Die anderen Antworten sind in Ordnung, aber diese hebt anhand eines aktuellen Beispiels einige ziemlich wichtige Fallstricke bei der Animation von Einschränkungen hervor. Ich habe viele Variationen durchlaufen, bevor mir Folgendes klar wurde:

Machen Sie die Einschränkungen, auf die Sie abzielen möchten, zu Klassenvariablen, um eine starke Referenz zu halten. In Swift habe ich faule Variablen verwendet:

lazy var centerYInflection:NSLayoutConstraint = {
       let temp =  self.view.constraints.filter({ $0.firstItem is MNGStarRating }).filter ( { $0.secondItem is UIWebView }).filter({ $0.firstAttribute == .CenterY }).first
        return temp!
}()

Nach einigem Experimentieren stellte ich fest, dass man die Einschränkung aus der Ansicht ÜBER (auch bekannt als die Übersicht) der beiden Ansichten, in denen die Einschränkung definiert ist, erhalten MUSS. Im folgenden Beispiel (sowohl MNGStarRating als auch UIWebView sind die beiden Arten von Elementen, zwischen denen ich eine Einschränkung erstelle, und sie sind Unteransichten in self.view).

Filterverkettung

Ich nutze Swifts Filtermethode, um die gewünschte Einschränkung zu trennen, die als Wendepunkt dient. Man könnte auch viel komplizierter werden, aber Filter macht hier einen guten Job.

Animieren von Constraints mit Swift

Nota Bene - Dieses Beispiel ist die Storyboard/Code-Lösung und setzt voraus, dass im Storyboard Standardeinschränkungen festgelegt wurden. Die Änderungen können dann mit Code animiert werden.

Angenommen, Sie erstellen eine Eigenschaft, um nach genauen Kriterien zu filtern und zu einem bestimmten Wendepunkt für Ihre Animation zu gelangen (natürlich können Sie auch nach einem Array filtern und eine Schleife durchlaufen, wenn Sie mehrere Einschränkungen benötigen):

lazy var centerYInflection:NSLayoutConstraint = {
    let temp =  self.view.constraints.filter({ $0.firstItem is MNGStarRating }).filter ( { $0.secondItem is UIWebView }).filter({ $0.firstAttribute == .CenterY }).first
    return temp!
}()

....

Etwas später...

@IBAction func toggleRatingView (sender:AnyObject){

    let aPointAboveScene = -(max(UIScreen.mainScreen().bounds.width,UIScreen.mainScreen().bounds.height) * 2.0)

    self.view.layoutIfNeeded()


    //Use any animation you want, I like the bounce in springVelocity...
    UIView.animateWithDuration(1.0, delay: 0.0, usingSpringWithDamping: 0.3, initialSpringVelocity: 0.75, options: [.CurveEaseOut], animations: { () -> Void in

        //I use the frames to determine if the view is on-screen
        if CGRectContainsRect(self.view.frame, self.ratingView.frame) {

            //in frame ~ animate away
            //I play a sound to give the animation some life

            self.centerYInflection.constant = aPointAboveScene
            self.centerYInflection.priority = UILayoutPriority(950)

        } else {

            //I play a different sound just to keep the user engaged
            //out of frame ~ animate into scene
            self.centerYInflection.constant = 0
            self.centerYInflection.priority = UILayoutPriority(950)
            self.view.setNeedsLayout()
            self.view.layoutIfNeeded()
         }) { (success) -> Void in

            //do something else

        }
    }
}

Die vielen falschen Kurven

Diese Notizen sind wirklich eine Reihe von Tipps, die ich für mich selbst geschrieben habe. Ich habe alle Verbote persönlich und schmerzhaft ausgeführt. Hoffentlich kann dieser Leitfaden andere verschonen.

  1. Achten Sie auf zPositioning. Manchmal, wenn anscheinend nichts passiert, sollten Sie einige der anderen Ansichten ausblenden oder den Ansichtsdebugger verwenden, um Ihre animierte Ansicht zu finden. Ich habe sogar Fälle gefunden, in denen ein benutzerdefiniertes Laufzeitattribut in der XML eines Storyboards verloren ging und dazu führte, dass die animierte Ansicht (während der Arbeit) abgedeckt wurde.

  2. Nehmen Sie sich immer eine Minute Zeit, um die Dokumentation (neu und alt), die Schnellhilfe und die Überschriften zu lesen. Apple nimmt immer wieder Änderungen vor, um die AutoLayout-Einschränkungen besser zu verwalten (siehe Stapelansichten). Oder zumindest das AutoLayout Cookbook . Denken Sie daran, dass die älteren Dokumentationen/Videos manchmal die besten Lösungen bieten.

  3. Spielen Sie mit den Werten in der Animation und erwägen Sie, andere animateWithDuration-Varianten zu verwenden.

  4. Codieren Sie bestimmte Layoutwerte nicht fest als Kriterien zum Bestimmen von Änderungen an anderen Konstanten. Verwenden Sie stattdessen Werte, mit denen Sie die Position der Ansicht bestimmen können. CGRectContainsRect ist ein Beispiel

  5. Zögern Sie nicht, bei Bedarf die Layoutränder zu verwenden, die einer Ansicht zugeordnet sind, die an der Einschränkungsdefinition let viewMargins = self.webview.layoutMarginsGuide: beteiligt ist
  6. Machen Sie keine Arbeit, die Sie nicht erledigen müssen. Für alle Ansichten mit Einschränkungen im Storyboard gelten Einschränkungen für die Eigenschaft self.viewName.constraints
  7. Ändern Sie Ihre Prioritäten für alle Einschränkungen auf weniger als 1000. Ich habe meine auf 250 (niedrig) oder 750 (hoch) im Storyboard festgelegt. (Wenn Sie versuchen, eine 1000-Priorität in Code zu ändern, stürzt die App ab, da 1000 erforderlich ist.)
  8. Versuchen Sie nicht sofort, activateConstraints und disableConstraints zu verwenden (sie haben ihren Platz, aber wenn Sie nur lernen oder ein Storyboard mit diesen verwenden, bedeutet dies wahrscheinlich, dass Sie zu viel tun - sie haben jedoch einen Platz, wie unten gezeigt).
  9. Erwägen Sie nicht, addConstraints/removeConstraints zu verwenden, es sei denn, Sie fügen dem Code tatsächlich eine neue Einschränkung hinzu. Ich habe festgestellt, dass ich die Ansichten im Storyboard meistens mit den gewünschten Einschränkungen anlege (die Ansicht außerhalb des Bildschirms platzieren) und dann im Code die zuvor im Storyboard erstellten Einschränkungen animiere, um die Ansicht zu verschieben.
  10. Ich habe viel verschwendete Zeit damit verbracht, Einschränkungen mit der neuen NSAnchorLayout-Klasse und Unterklassen aufzubauen. Diese funktionieren einwandfrei, aber es dauerte eine Weile, bis mir klar wurde, dass alle Einschränkungen, die ich benötigte, bereits im Storyboard vorhanden waren. Wenn Sie Einschränkungen in Code erstellen, verwenden Sie mit Sicherheit diese Methode, um Ihre Einschränkungen zu aggregieren:

Schnelle Auswahl von Lösungen, die bei der Verwendung von Storyboards ZU VERMEIDEN sind

private var _nc:[NSLayoutConstraint] = []
    lazy var newConstraints:[NSLayoutConstraint] = {

        if !(self._nc.isEmpty) {
            return self._nc
        }

        let viewMargins = self.webview.layoutMarginsGuide
        let minimumScreenWidth = min(UIScreen.mainScreen().bounds.width,UIScreen.mainScreen().bounds.height)

        let centerY = self.ratingView.centerYAnchor.constraintEqualToAnchor(self.webview.centerYAnchor)
        centerY.constant = -1000.0
        centerY.priority = (950)
        let centerX =  self.ratingView.centerXAnchor.constraintEqualToAnchor(self.webview.centerXAnchor)
        centerX.priority = (950)

        if let buttonConstraints = self.originalRatingViewConstraints?.filter({

            ($0.firstItem is UIButton || $0.secondItem is UIButton )
        }) {
            self._nc.appendContentsOf(buttonConstraints)

        }

        self._nc.append( centerY)
        self._nc.append( centerX)

        self._nc.append (self.ratingView.leadingAnchor.constraintEqualToAnchor(viewMargins.leadingAnchor, constant: 10.0))
        self._nc.append (self.ratingView.trailingAnchor.constraintEqualToAnchor(viewMargins.trailingAnchor, constant: 10.0))
        self._nc.append (self.ratingView.widthAnchor.constraintEqualToConstant((minimumScreenWidth - 20.0)))
        self._nc.append (self.ratingView.heightAnchor.constraintEqualToConstant(200.0))

        return self._nc
    }()

Wenn Sie einen dieser oder einfachere Tipps vergessen, z. B. wo das layoutIfNeeded hinzugefügt werden soll, passiert höchstwahrscheinlich nichts: In diesem Fall haben Sie möglicherweise eine halbherbe Lösung wie die folgende:

NB - Nehmen Sie sich einen Moment Zeit, um den folgenden Abschnitt zum automatischen Layout und die Originalanleitung zu lesen. Es gibt eine Möglichkeit, diese Techniken zu verwenden, um Ihre dynamischen Animatoren zu ergänzen.

UIView.animateWithDuration(1.0, delay: 0.0, usingSpringWithDamping: 0.3, initialSpringVelocity: 1.0, options: [.CurveEaseOut], animations: { () -> Void in

            //
            if self.starTopInflectionPoint.constant < 0  {
                //-3000
                //offscreen
                self.starTopInflectionPoint.constant = self.navigationController?.navigationBar.bounds.height ?? 0
                self.changeConstraintPriority([self.starTopInflectionPoint], value: UILayoutPriority(950), forView: self.ratingView)

            } else {

                self.starTopInflectionPoint.constant = -3000
                 self.changeConstraintPriority([self.starTopInflectionPoint], value: UILayoutPriority(950), forView: self.ratingView)
            }

        }) { (success) -> Void in

            //do something else
        }

    }

Snippet aus dem AutoLayout-Handbuch (beachten Sie, dass das zweite Snippet für die Verwendung von OS X vorgesehen ist). Übrigens - Soweit ich sehen kann, ist dies nicht mehr im aktuellen Handbuch enthalten. Die bevorzugten Techniken entwickeln sich weiter.

Animieren von Änderungen, die durch das automatische Layout vorgenommen wurden

Wenn Sie die volle Kontrolle über das Animieren von Änderungen benötigen, die von Auto Layout vorgenommen werden, müssen Sie die Änderungen an den Einschränkungen programmgesteuert vornehmen. Das Grundkonzept ist für iOS und OS X gleich, es gibt jedoch einige geringfügige Unterschiede.

In einer iOS-App würde Ihr Code ungefähr so ​​aussehen:

[containerView layoutIfNeeded]; // Ensures that all pending layout operations have been completed
[UIView animateWithDuration:1.0 animations:^{
     // Make all constraint changes here
     [containerView layoutIfNeeded]; // Forces the layout of the subtree animation block and then captures all of the frame changes
}];

Verwenden Sie in OS X den folgenden Code, wenn Sie Animationen mit Ebenen verwenden:

[containterView layoutSubtreeIfNeeded];
[NSAnimationContext runAnimationGroup:^(NSAnimationContext *context) {
     [context setAllowsImplicitAnimation: YES];
     // Make all constraint changes here
     [containerView layoutSubtreeIfNeeded];
}];

Wenn Sie keine Ebenenanimationen verwenden, müssen Sie die Konstante mit dem Animator der Einschränkung animieren:

[[constraint animator] setConstant:42];

Für diejenigen, die besser visuell lernen, sehen Sie sich dies früh an Video von Apple .

Pass gut auf

Oft gibt es in der Dokumentation kleine Notizen oder Code-Teile, die zu größeren Ideen führen. Zum Beispiel ist es eine gute Idee, dynamische Animatoren mit Auto-Layout-Einschränkungen zu versehen.

Viel Glück und möge die Macht mit dir sein.

13
Tommie C.

Schnelle Lösung:

yourConstraint.constant = 50
UIView.animate(withDuration: 1.0, animations: {
    yourView.layoutIfNeeded
})
6
Nazariy Vlizlo

Arbeitslösung 100% Swift 3.1

ich habe alle Antworten gelesen und möchte den Code und die Hierarchie der Zeilen teilen, die ich in all meinen Anwendungen verwendet habe, um sie korrekt zu animieren. Einige Lösungen funktionieren hier nicht. Sie sollten sie in diesem Moment auf langsameren Geräten, z. B. iPhone 5, überprüfen.

self.view.layoutIfNeeded() // Force lays of all subviews on root view
UIView.animate(withDuration: 0.5) { [weak self] in // allowing to ARC to deallocate it properly
       self?.tbConstraint.constant = 158 // my constraint constant change
       self?.view.layoutIfNeeded() // Force lays of all subviews on root view again.
}
5
C0mrade

Ich habe versucht, Constraints zu animieren, und es war nicht einfach, eine gute Erklärung zu finden.

Was andere Antworten aussagen, ist völlig richtig: Sie müssen [self.view layoutIfNeeded]; innerhalb von animateWithDuration: animations: aufrufen. Der andere wichtige Punkt ist jedoch, Zeiger für jedes NSLayoutConstraint zu haben, das Sie animieren möchten.

Ich habe ein Beispiel in GitHub erstellt .

4
Gabriel.Massana

Funktionierende und gerade getestete Lösung für Swift 3 mit Xcode 8.3.3:

self.view.layoutIfNeeded()
self.calendarViewHeight.constant = 56.0

UIView.animate(withDuration: 0.5, delay: 0.0, options: UIViewAnimationOptions.curveEaseIn, animations: {
        self.view.layoutIfNeeded()
    }, completion: nil)

Denken Sie daran, dass self.calendarViewHeight eine Einschränkung für eine benutzerdefinierte Ansicht (CalendarView) ist. Ich habe .layoutIfNeeded () bei self.view und NICHT bei self.calendarView aufgerufen

Ich hoffe das hilft.

4
Edoardo Vicoli

Es gibt einen Artikel darüber: http://weblog.invasivecode.com/post/42362079291/auto-layout-and-core-animation-auto-layout-was

In dem codierte er wie folgt:

- (void)handleTapFrom:(UIGestureRecognizer *)gesture {
    if (_isVisible) {
        _isVisible = NO;
        self.topConstraint.constant = -44.;    // 1
        [self.navbar setNeedsUpdateConstraints];  // 2
        [UIView animateWithDuration:.3 animations:^{
            [self.navbar layoutIfNeeded]; // 3
        }];
    } else {
        _isVisible = YES;
        self.topConstraint.constant = 0.;
        [self.navbar setNeedsUpdateConstraints];
        [UIView animateWithDuration:.3 animations:^{
            [self.navbar layoutIfNeeded];
        }];
    }
}

Ich hoffe es hilft.

3
D.D.

Im Kontext der Einschränkungsanimation möchte ich eine bestimmte Situation erwähnen, in der ich eine Einschränkung sofort innerhalb einer Benachrichtigung mit geöffneter Tastatur animiert habe.

Die Einschränkung definierte einen oberen Bereich von einem Textfeld bis zum oberen Rand des Containers. Beim Öffnen der Tastatur dividiere ich die Konstante einfach durch 2.

Es ist mir nicht gelungen, eine konsistente Animation mit weichen Einschränkungen direkt in der Tastaturbenachrichtigung zu erzielen. In etwa der Hälfte der Fälle würde die Ansicht einfach an ihre neue Position springen - ohne zu animieren.

Mir ist aufgefallen, dass aufgrund des Öffnens der Tastatur möglicherweise zusätzliche Layouts erstellt werden. Durch Hinzufügen eines einfachen dispatch_after-Blocks mit einer Verzögerung von 10 ms wurde die Animation jedes Mal ausgeführt - kein Springen.

1
ivanferdelja