Soy de la actualización de una app antigua con un AdBannerView y cuando no hay ningún anuncio, que se deslice fuera de la pantalla. Cuando hay un anuncio que se desliza sobre la pantalla. Cosas básicas.

Estilo antiguo, he establecido el marco en un bloque de animación.
Nuevo estilo, tengo un IBOutlet para el auto-diseño de restricción que determina la posición Y, en este caso es la distancia desde la parte inferior de la superview, y modificar la constante:

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

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

Y la bandera se mueve, exactamente como se esperaba, pero no animación.

ACTUALIZACIÓN: he re-visto La WWDC 12 de hablar de las Mejores Prácticas para el dominio de Diseño Automático que cubre la animación. Se describe cómo actualizar las restricciones de uso de CoreAnimation:

¿Cómo puedo animar restricción de cambios?
¿Cómo puedo animar restricción de cambios?

He probado con el siguiente código, pero obtener los mismos resultados exactos:

- (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;
}

En una nota de lado, he comprobado en numerosas ocasiones y este se ejecuta en el principal hilo.

  • Nunca he visto a tantos votos ofrecidos por una pregunta y una respuesta en un error tipográfico en ASÍ que antes de
  • Si hay un error tipográfico en la respuesta, usted debe editar la respuesta. Por eso son editables.
  • Sería más útil si usted señaló el error, así que sabía que cuando el error fue. Se podría modificar la respuesta de usted y corregido la errata de ahorro de todos los demás nuestra diatriba. Hice editarlo para quitar la constante de la animación bloque, si es eso a lo que te referías.
  • No sé lo que la errata es. Yo estaba respondiendo a los comentarios de arriba.
  • A continuación, la errata es la cuestión. Estúpidamente me estaba escribiendo «setNeedsLayout» en lugar de «layoutIfNeeded». Se muestra claramente en mi pregunta cuando me corte y pegue mi código con el error y las capturas de pantalla con el comando correcto. Sin embargo, no parecían notarlo hasta que alguien lo señaló.
InformationsquelleAutor DBD | 2012-09-27

13 Comentarios

  1. 1620

    Dos notas importantes:

    1. Usted necesita llamar a layoutIfNeeded dentro de la animación bloque. Apple realmente recomienda que usted la llame una vez antes de que el bloque de animación para asegurarse de que todos los pendientes de diseño de las operaciones se han completado

    2. Usted necesita llamar específicamente en el vista principal (por ejemplo,self.view), no el niño que tiene las limitaciones que se adjunta a la misma. Al hacerlo actualización todos limitados puntos de vista, incluyendo la animación de otros puntos de vista que podría ser limitada a la vista de que ha cambiado la restricción (por ejemplo, Ver B se adjunta a la parte inferior de la Vista de Una y que acaba de cambiar la Vista de la parte superior de desplazamiento y desea Ver B a animar con ella)

    Intente esto:

    Objective-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 3

    UIView.animate(withDuration: 5) {
        self._addBannerDistanceFromBottomConstraint.constant = 0
        self.view.layoutIfNeeded()
    }
    • Usted ha tratado de hacer el cambio en la constante y layoutIfNeeded tanto en el interior de la animación bloque, derecho?
    • sí, lo he probado. Yo lo tenía de esa manera original y modificada sólo después de un segundo reloj en la WWDC de vídeo.
    • No hay ninguna otra restricción de cambios. Las limitaciones en el banner de publicidad son la distancia desde el borde izquierdo(0), la distancia desde el borde de la derecha(0), altura fija(32) y la distancia de la parte inferior(0). No existen otras restricciones asociadas con la bandera. Comentario de la restricción de cambio que significa que no ocurre nada.
    • Usted sabe lo que… su respuesta obras. La WWDC de obras…. mi visión se produce un error. Por alguna razón me tomó una semana para darse cuenta de que me estaba llamando setNeedsLayout en lugar de layoutIfNeeded. Estoy un poco horrorizado por la cantidad de horas que pasé sin darse cuenta de que yo sólo acaba de escribir mal el nombre del método.
    • La solución funciona, pero no es necesario cambiar la restricción constante de plazo la animación de bloque. Es totalmente bien para establecer la restricción de una vez antes de dar inicio a la animación. Usted debe modificar su respuesta.
    • Esto no funciona para mí al principio y luego me di cuenta de que usted necesita llamar a layoutIfNeeded en la vista principal, no a la vista de las restricciones se aplican.
    • el uso de layoutIfNeeded va a animar a todos los subvista actualiza no sólo la restricción de cambio. cómo hacer u animar la restricción sólo cambio?
    • Bueno. Trabajo bien en iOS 8.
    • funciona muy bien, gracias. pero solo para dejarlo claro: es pura locura por las limitaciones que, básicamente, existen en una forma totalmente diferente ámbito de la animación. esto realmente tripas algunos muy limpio mayores de animación de la lógica.
    • Yo no podía conseguir trabajo, pensando que tenía que llamar a layoutIfNeeded en la vista principal de la restricción. He cambiado a la vista principal del controlador de vista y ahora funciona de maravilla
    • También hay que tener cuidado con UILabels. Algún tipo de animación con UILabel funciona de manera diferente con el mismo código con el simple UIView . Por desgracia, no sé por qué. Y si alguien sabe realmente aprecio a comentar yo.
    • Esto funciona perfectamente y que me gustaría señalar estoy llamando layoutIfNeeded en la subvista, no es de los padres a la vista. No muy segura de por qué son otros los que tienen que llamar a los padres.
    • «Apple realmente recomienda que usted la llame una vez antes de que el bloque de animación para asegurarse de que todos los pendientes de diseño de las operaciones se han completado», gracias, nunca pensé en eso, pero tiene sentido.
    • Me gustó esto, pero quería que la Velocidadinicial efecto, y encontré esto funciona muy bien en Swift: UIView.animateWithDuration(0.3, delay: 0, opciones: UIViewAnimationOptions.CurveEaseIn, animaciones: { self.vista.layoutIfNeeded() }, finalización: nil)
    • Esto no funciona con las restricciones relacionadas. Digamos que animar una altura con esto, la altura de la B, que es dependiente de la altura será más corto cuando la altura es mucho, y más cuando la altura es corto. B lamentablemente, cambio de inmediato y NO se animan.
    • A veces la animación no animar y ejecutar directamente hasta su finalización. Cómo resolverlo?
    • He implementado la solución varias veces con éxito, hoy no trabajo para una nueva aplicación. Encuentra lo que necesita para llamar self.view.layoutIfNeeded() en la animación de bloque, NO de la finalización del bloque. Doh!
    • El «Apple realmente recomienda» enlace está roto. Si alguien sabe la nueva dirección URL puede que actualice?
    • Ejemplo de código se vería mejor si en la devolución de llamada que uno llamaría [subview.superview layoutIfNeeded];
    • El programa de instalación de toda restricción que usted no desea animar -> llame layoutIfNeeded y, a continuación, el programa de instalación de animación bloque con que una restricción a la que desea animar, otro layoutIfNeeded incluido.
    • Sí, funciona en iOS 11 beta5, y no es necesario actualizar la restricción en el interior de la animación bloque.
    • Gracias – esta resuelto un problema de diseño que yo estaba experimentando en iOS 11!
    • Inicialmente no trabajó para mí, pero luego me di cuenta de que tengo que poner isHidden = false fuera de la animación bloque y dentro de la finalización del bloque en su lugar
    • Estoy confundido acerca de la manera de actualizar las limitaciones y escribió this. Puede usted por favor, eche un vistazo?
    • Impresionante.! Gracias por tu sugerencia.
    • Gracias! Guardar mi día!

  2. 106

    Agradezco la respuesta, pero creo que sería bueno tomar un poco más.

    El bloque básico de la animación de la documentación

    [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
    }];

    pero realmente esta es una muy simplista escenario. Lo que si quiero animar subvista restricciones a través de la updateConstraints método?

    Un bloque de animación que se llama el subvistas updateConstraints método

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

    La updateConstraints método se reemplaza en el UIView subclase y debe llamar a super en la final del método.

    - (void)updateConstraints
    {
        //Update some constraints
    
        [super updateConstraints];
    }

    El Autodiseño De Guía deja mucho que desear, pero es que vale la pena leer. Yo mismo estoy utilizando esto como parte de un UISwitch que alterna una subvista con un par de UITextFields con un simple y sutil colapso de animación (0.2 segundos). Las restricciones para la subvista que se manejan en el UIView subclases updateConstraints métodos descritos anteriormente.

    • Al llamar a todos los métodos anteriores en self.view (y no en una subvista de ese punto de vista), llamando updateConstraintsIfNeeded no es necesario (porque setNeedsLayout también provoca updateConstraints de ese punto de vista). Podría ser trivial para la mayoría, pero no era para mí, hasta ahora 😉
    • Es difícil comentar sin conocer la completa interacción de Autodiseño y los muelles y amortiguadores de diseño en su caso particular. Estoy hablando completamente acerca de un puro diseño automático escenario. Yo sería curioso saber exactamente qué está sucediendo en su layoutSubviews método.
    • translatesAutoresizingMaskIntoConstraints = NO; Si desea puro diseño automático que sin duda debe deshabilitar esta.
    • Yo no he visto eso, pero yo no puedo hablar del tema sin código. Tal vez usted podría burlarse de un formato tableview y pegar en GitHub?
    • Lo siento, yo no uso gitHub 🙁
    • Atención: Si está utilizando el UIViewAnimationOptionBeginFromCurrentState las restricciones de diseño se establece que ANTES la animación!
    • Estoy confundido acerca de la manera de actualizar las limitaciones y escribió this. Puede usted por favor, eche un vistazo?

  3. 66

    Por lo general, usted sólo tiene que actualizar las restricciones y llame a layoutIfNeeded dentro de la animación bloque. Este puede ser el cambio de la .constant propiedad de un NSLayoutConstraint, la adición de eliminar las restricciones de (iOS 7), o cambiar el .active propiedad de restricciones (iOS 8 & 9).

    Código De Ejemplo:

    [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];
    }];

    Ejemplo De Configuración:

    ¿Cómo puedo animar restricción de cambios?

    Controversia

    Hay algunas preguntas acerca de si la restricción debe ser cambiado antes de la animación de bloque, o dentro de (ver respuestas anteriores).

    La siguiente es una conversación de Twitter entre Martin Pilkington que enseña iOS, y Ken Ferry que escribió Diseño Automático. Ken explica que a pesar de que el cambio de las constantes fuera de la animación bloque en la actualidad puede trabajo, no es seguro y que realmente debería ser el cambio dentro de la animación de bloque.
    https://twitter.com/kongtomorrow/status/440627401018466305

    Animación:

    ¿Cómo puedo animar restricción de cambios?

    Ejemplo De Proyecto

    Aquí es un proyecto simple que muestra cómo un punto de vista puede ser animado. Es el uso de Objective C y anima a la vista por el cambio de la .active propiedad de varias limitaciones.
    https://github.com/shepting/SampleAutoLayoutAnimation

    • +1 para mostrar un ejemplo de uso de la nueva bandera activa. También, el cambio de la restricción fuera de la animación bloque siempre se sentía como un hack para mí
    • Me planteó una cuestión en github porque esta solución no funciona para mover la vista a donde estaba. Creo que el cambio de activos no es la solución correcta y usted debe ser el cambio de la prioridad en su lugar. Colocar la parte superior a 750, y la parte inferior a 250, a continuación, en el código de alternar entre UILayoutPriorityDefaultHigh y UILayoutPriorityDefaultLow.
    • Otra razón para la actualización dentro del bloque es que los aislamientos de los cambios de código de llamada que puede suceder a llamar también a layoutIfNeeded. (y gracias por el enlace de Twitter)
    • Gran respuesta. Especialmente porque usted menciona Martin y Ken conversación acerca de esto.
    • Estoy confundido acerca de la manera de actualizar las limitaciones y escribió this. Puede usted por favor, eche un vistazo?
  4. 33
    //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];
    }];
  5. 21

    Swift 4 solución

    UIView.animate

    Tres simples pasos:

    1. Cambiar las restricciones, por ejemplo:

      heightAnchor.constant = 50
    2. Decir la que contiene view que su diseño es sucia y que el autodiseño debe recalcular el diseño:

      self.view.setNeedsLayout()
    3. De animación bloque de decirle a la disposición para volver a calcular la distribución, que es el equivalente de la configuración de los marcos directamente (en este caso el autodiseño va a establecer los marcos):

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

    Completa ejemplo más sencillo:

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

    Nota al margen

    Hay un opcional 0 paso – antes de cambiar las limitaciones que quisiera llamar self.view.layoutIfNeeded() para asegurarse de que el punto de partida para la animación desde el estado con las viejas restricciones aplicada (en caso de que hubo algunas otras restricciones de cambios que no deben ser incluidos en la animación):

    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()
    }

    UIViewPropertyAnimator

    Ya que con iOS 10 tenemos una nueva animación en el mecanismo de UIViewPropertyAnimator, debemos saber que, básicamente, el mismo mecanismo se aplica a ella. Los pasos son básicamente los mismos:

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

    Desde animator es una encapsulación de la animación, podemos mantener la referencia a él y a llamar más tarde. Sin embargo, ya en el bloque de animación, se le dice al diseño automático para volver a calcular los marcos, tenemos que cambiar las restricciones antes de llamar a startAnimation. Por lo tanto, algo como esto es posible:

    //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()

    La orden de cambio de las restricciones y el inicio de un animador es importante, si nos cambian las limitaciones y salir de nuestro animador para algún momento posterior, la siguiente redibujar el ciclo puede invocar el diseño automático de recálculo y el cambio no va a ser animada.

    También, recuerda que un solo animador no es reutilizable – una vez que se ejecuta, no se puede «ejecutar» de ella. Así que supongo que no hay realmente una buena razón para mantener el animador de todo, a menos que usamos para controlar una animación interactiva.

    • agradable y limpio respuesta gracias
  6. 12

    Guión gráfico, Código, Consejos y un par de Trampas

    Las otras respuestas son igual de bien, pero este, se destacan algunas bastante importante trampas de la animación de restricciones mediante un ejemplo reciente. Me fui a través de una gran cantidad de variaciones antes de que me di cuenta de lo siguiente:

    Hacer las limitaciones que desea centrarse en las variables de la Clase mantener una fuerte referencia. En Swift he utilizado perezoso variables:

    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!
    }()

    Después de algunos experimentos, he observado que uno DEBE obtener la restricción desde el punto de vista por ENCIMA de (aka el superview) los dos puntos de vista, donde se define la restricción. En el ejemplo siguiente (ambos MNGStarRating y UIWebView son los dos tipos de elementos que lo estoy creando una restricción entre, y son subvistas dentro de uno mismo.vista).

    Filtro De Encadenamiento De

    Puedo tomar ventaja de Swift método de filtro para separar el deseado restricción que servirá como el punto de inflexión. También se podría conseguir mucho más complicado, pero con el filtro de un buen trabajo aquí.

    La Animación De Las Restricciones En El Uso De Swift

    Nota Bene – Este ejemplo es el guión gráfico/solución de código y se supone
    uno ha hecho de las restricciones predeterminadas en el guión gráfico. Entonces, uno puede
    animar los cambios mediante código.

    Suponiendo que crear una propiedad para filtro con la precisión de los criterios y llegar a un determinado punto de inflexión para la animación (por supuesto, usted puede también filtrar por una matriz y el bucle a través de si usted necesita varias restricciones):

    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!
    }()

    ….

    Algún tiempo después…

    @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
    
            }
        }
    }

    Los muchos giros equivocados

    Estas notas son en realidad un conjunto de consejos que me escribió para mí. Yo hice todo lo que no se debe hacer personalmente y dolorosamente. Esperamos que esta guía pueda prescindir de los demás.

    1. Mirar hacia fuera para zPositioning. A veces cuando no hay nada al parecer
      ocurre, usted debe ocultar algunos de los otros puntos de vista o utilizar la vista
      depurador para localizar la animación del punto de vista. Incluso he encontrado casos en los que un Usuario Definido en tiempo de ejecución
      Atributo, se perdió en un guión del xml y llevado a la animación
      de vista, cubierto (mientras se trabaja).

    2. Siempre tome un minuto para leer la documentación (nuevo y viejo), Rápido
      Ayuda, y los encabezados. Apple sigue haciendo un montón de cambios para mejor
      gestionar el diseño Automático de restricciones (ver la pila de puntos de vista). O, al menos, el Autodiseño Libro De Cocina. Tenga en cuenta que a veces las mejores soluciones están en la edad de documentación/videos.

    3. Jugar con los valores de la animación y considerar el uso de
      otros animateWithDuration variantes.

    4. No codificar diseño específico de los valores como criterios para la determinación de
      los cambios constantes, en lugar de utilizar los valores que le permiten
      determinar la ubicación de la vista. CGRectContainsRect es uno
      ejemplo

    5. Si es necesario, no dude en utilizar el diseño de los márgenes asociados con
      una vista de la participación en la definición de la restricción
      let viewMargins = self.webview.layoutMarginsGuide: es por ejemplo
    6. No hacer el trabajo que usted no tiene que hacer, todos los puntos de vista con las restricciones en la
      storyboard tienen restricciones adjunta a la propiedad
      auto.viewName.restricciones
    7. Cambiar sus prioridades para cualquier restricción a menos de 1000. Me puse
      mina a 250 (baja) o 750 (alta) en el guión; (si intenta cambiar un 1000 prioridad a nada en el código, a continuación, la aplicación se bloqueará porque 1000 es necesario)
    8. Considerar no de inmediato tratando de usar activateConstraints y
      deactivateConstraints (tienen su lugar, pero cuando acaba de aprendizaje o si usted está usando un guión utilizando estos probablemente significa que su hacer demasiado ~ tienen un lugar, aunque como se ve a continuación)
    9. Considerar la posibilidad de no usar addConstraints /removeConstraints a menos que se
      realmente la adición de una nueva restricción en el código. He encontrado que la mayoría de las veces que me
      diseño de las vistas en el guión gráfico deseados, con restricciones (colocación de
      la vista fuera de la pantalla), luego en el código, me animan las limitaciones previamente creado en el guión gráfico para mover la vista.
    10. Me pasé un montón de tiempo perdido la construcción de las restricciones con la nueva
      NSAnchorLayout de clases y subclases. Estos funcionan bien pero
      me tomó un tiempo para darse cuenta de que todas las restricciones que necesitaba
      ya existía en el guión gráfico. Si usted construir restricciones en el código
      a continuación, la mayoría sin duda el uso de este método para agregar a sus limitaciones:

    Muestra rápida De Soluciones para EVITAR al usar los Storyboards

    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
        }()

    Si usted se olvida de uno de estos consejos o las más simples, tales como dónde agregar el layoutIfNeeded, más probable es que no pase nada: En cuyo caso puede que tenga un half baked solución como esta:

    NB – Tome un momento para leer el Autodiseño de la Sección de Abajo y la
    guía original. Hay una manera de utilizar estas técnicas para complementar
    su Dinámica de Animadores.

    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
            }
    
        }

    Fragmento de la Guía de diseño Automático (nota: el segundo fragmento es para el uso de OS X). Por CIERTO, Esto ya no es en la actual guía por lo que puedo ver. Las técnicas preferidas siguen evolucionando.

    La animación de los Cambios Realizados por el Diseño Automático

    Si necesita control total sobre la animación de los cambios realizados por el Diseño Auto, usted debe hacer su restricción de los cambios de programación. El concepto básico es el mismo para ambos iOS y OS X, pero hay algunas diferencias menores.

    En una aplicación para iOS, el código sería algo como lo siguiente:

    [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
    }];

    En OS X, utilice el siguiente código cuando se utiliza la capa de la copia de animaciones:

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

    Cuando no estás usando la capa de la copia de animaciones, usted debe animar a la constante mediante la restricción del animador:

    [[constraint animator] setConstant:42];

    Para aquellos que aprenden mejor visualmente echa un vistazo a este temprano vídeo de Apple.

    Atención Cercana De La Paga

    A menudo en la documentación hay pequeñas notas o fragmentos de código que conducen a las grandes ideas. Por ejemplo, fijación automática de restricciones de diseño a la dinámica de los animadores es una gran idea.

    Buena Suerte y que la Fuerza esté con usted.

  7. 6

    Solución rápida:

    yourConstraint.constant = 50
    UIView.animate(withDuration: 1.0, animations: {
        yourView.layoutIfNeeded
    })
  8. 5

    La Solución De Trabajo De 100% Swift 3.1

    he leído todas las respuestas y quiero compartir el código y la jerarquía de las líneas que he usado en todos mis aplicaciones para animar correctamente, Algunas de las soluciones que aquí no está trabajando, usted debe comprobar de ellos en los dispositivos más lentos e.g iPhone 5 en este momento.

    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.
    }
  9. 4

    Yo estaba tratando de animar Limitaciones y no fue muy fácil para encontrar una buena explicación.

    ¿Qué otras respuestas están diciendo es totalmente cierto: usted necesita llamar a [self.view layoutIfNeeded]; dentro de animateWithDuration: animations:. Sin embargo, el otro punto importante es tener punteros para cada NSLayoutConstraint que desea animar.

    He creado un ejemplo en GitHub.

  10. 4

    De trabajo y prueba de la solución para Swift 3 con 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)

    Solo ten en mente que yo.calendarViewHeight es una restricción se refiere a un customView (CalendarView). Me llamó la .layoutIfNeeded() en auto.la vista y NO en auto.calendarView

    Espero que esta ayuda.

  11. 2

    Hay un artículo que habla sobre esto:
    http://weblog.invasivecode.com/post/42362079291/auto-layout-and-core-animation-auto-layout-was

    En el cual, él codificado como este:

    - (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];
            }];
        }
    }

    Espero que ayude.

  12. 1

    En el contexto de restricción de animación, me gustaría mencionar una situación específica donde he animado una restricción de inmediato dentro de un keyboard_opened notificación.

    Restricción definida en un espacio de un campo de texto a la parte superior del contenedor. Sobre el teclado de apertura, acabo de dividir la constante por 2.

    Yo era incapaz de lograr un conistent suave de la restricción de la animación directamente en el teclado de la notificación. Aproximadamente la mitad de las veces vista acaba de saltar a su nueva posición – sin animación.

    Se me ocurrió que podría haber algunos adicionales publicación sucediendo como resultado de teclado de apertura.
    La adición de un simple dispatch_after bloque con un retardo de 10 ms hizo que la animación se ejecute cada vez que – no saltar.

  13. -1

    Para los compañeros de Xamarians, aquí está la Xamarin.iOS/C# versión:

    UIView.Animate(5, () =>
    {
        _addBannerDistanceFromBottomConstraint.Constant = 0;
        View.LayoutIfNeeded();
    });

Dejar respuesta

Please enter your comment!
Please enter your name here