Lugar de crear dos UIImageViews, parece lógico simplemente cambiar el image de una vista. Si hago eso, ¿hay alguna forma de tener un fade/disolución cruzada entre las dos imágenes más que un instante el cambio?

  • Su edición se ha quitado una importante etiqueta. Por favor no hagan eso.
  • Pero aquí «objective-c» no una baja prioridad a la etiqueta! No quitar sólo para agregar «swift», esto no tiene sentido, es en realidad el límite de vandalismo…
  • Ok no voy a hacer repita la misma . Muchas gracias por su preocupación.
InformationsquelleAutor Josh Kahane | 2011-10-03

9 Comentarios

  1. 45

    Edit: hay una mejor solución de @algas a continuación.

    Otra manera de hacer esto es mediante el uso de predefinidos CAAnimation transiciones:

    CATransition *transition = [CATransition animation];
    transition.duration = 0.25;
    transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
    transition.type = kCATransitionFade;
    transition.delegate = self;
    [self.view.layer addAnimation:transition forKey:nil];
    view1.hidden = YES;
    view2.hidden = NO;

    Ver las Transiciones de Vista del proyecto de ejemplo de Apple: https://developer.apple.com/library/content/samplecode/ViewTransitions/Introduction/Intro.html#//apple_ref/doc/uid/DTS40007411

    • Perfecto! Añado parte de este código en SDWebImage del UIImageView (WebCache) de la categoría.
    • usted puede ser mejor usar el nuevo método a continuación por user577888.
    • Yo también estoy exponiendo mi imagen después de un SDWebImages de devolución de llamada de esa manera, pero por alguna razón en mi CollectionViewCell la imagen de la primera celda, es inicialmente el de la última celda visible si todas mis células actualización. Supongo que es algún tipo de almacenamiento en caché de la presentationLayer o algo?!? Alguna idea de qué podría ser?
    • Upvote para la edición de «hay una mejor solución de @algas a continuación.»
  2. 575

    Puede ser mucho más simple de usar el nuevo bloque, UIKit métodos de animación.

    Supongamos el siguiente código en el controlador de vista, y el UIImageView desea disolución cruzada es una subvista de sí mismo.ver direccionable a través de la propiedad de auto.imageView. Entonces todo lo que usted necesita es:

    UIImage * toImage = [UIImage imageNamed:@"myname.png"];
    [UIView transitionWithView:self.imageView
                      duration:5.0f
                       options:UIViewAnimationOptionTransitionCrossDissolve
                    animations:^{
                      self.imageView.image = toImage;
                    } completion:nil];

    Hecho.

    Y hacerlo en Swift, es así:

    let toImage = UIImage(named:"myname.png")
    UIView.transitionWithView(self.imageView,
                              duration:5,
                              options: UIViewAnimationOptions.TransitionCrossDissolve,
                              animations: { self.imageView.image = toImage },
                              completion: nil)

    Swift 3.0

     let toImage = UIImage(named:"myname.png")
     UIView.transition(with: self.imageView,
                       duration: 0.3,
                       options: .transitionCrossDissolve,
                       animations: {
                           self.imageView.image = toImage
                       },
                       completion: nil)
    • Las otras respuestas son correctas pero desfasado (y/o excesivamente detallado).
    • No es necesario hacer la transición en el super vista. Me las arreglé para hacer este trabajo especificando la UIImageView a sí mismo como el destino.
    • Esto no funciona con iOS 6.0+ ?? Sabe de una alternativa para iOS6?
    • Esto funciona bien en iOS6. Haga la prueba: github.com/algal/TrivialImageDissolveDemo .
    • Gracias por la corrección. De hecho llamadas en el auto.ver también imponer la especificada animación duración en otros subvistas de sí mismo.ver, por ejemplo, un botón. Voy a editar esta, más tarde, una vez que estoy 100% seguro de que no estoy perdiendo algún otro factor.
    • sólo una pequeña cosa. Usted debe pasar nil para el vacío de la finalización del bloque. Los bloques no son punteros a función (como se indica por el ^) y funcionar como un objetivo-c objeto. Si se pasa NULL, el compilador va a interpretar que como 0 o (void *)0. Si por alguna razón el código subyacente para transitionWithView:… accidentalmente envía un mensaje a la finalización de bloque (por ejemplo. [la finalización de copia]) sin comprobar su validez, esto dará lugar a un error. Así que usted debe utilizar siempre el objetivo-c, nil cuando la configuración de un bloque vacío.
    • Yo creo que lo que vemos es totalmente convincente en sus méritos, especialmente el punto de que los bloques se comportan como objective-c los objetos de modo que la ausencia de un bloque debe ser transmitida con nulo no NULO. Pero: tan cerca de como yo puedo decir, todo de Apple ejemplos de código pasar NULO no nulo cuando no hay ningún bloque. O ¿que cambio?
    • NULL y nulo valor idéntico. Ambos se definen a 0 y ni siquiera es probable que lleguen a cambiar. Por lo tanto, es seguro de usar NULL lugar o podrían usar nil.
    • sí sus valores son 0 pero son emitidos de manera diferente. NULL es arrojado a 0 o (void *)0, y nil es el reparto de la (id)0. Dependiendo de su compilador, el envío de un mensaje a NULL hará una advertencia a ocurrir, mientras que el envío de un mensaje (id)0 suprimir la advertencia. Por lo que tienden a utilizar nils siempre es un objetivo-C objeto involucrado y el uso de NULL siempre es un c/c++ objeto implicado.
    • Mi punto es que el uso de uno sobre el otro nunca va a causar un accidente, porque en el código compilado nivel son idénticos, y por razones prácticas, siempre será. La supresión de las advertencias del compilador es una buena idea, en general, sin embargo, decirle a la gente que es un error utilizar NULL en lugar de nil, es simplemente incorrecto.
    • T Pasar el valor NULL para un bloque es legal, siempre ha sido legal, y siempre va a ser legal.
    • No, no funciona en iOS 6 si la transición de un elástico de imagen a un no-elástico de la imagen. ( @VanDuTran )
    • +1 para el Swift poco. Este aspecto es cómo vamos a tener que escribir Cocoa-Touch respuestas a partir de ahora..
    • Acabo de perder una hora tratando de averiguar por qué mis imágenes que nunca se mostró. Resulta que yo necesitaba para llamar a [imageView sizeToFit] después de cambiar la imagen. FYI.
    • Tuve que envolver todo en un dispatch_after... para hacer que funcione. Presumiblemente, para asegurarse de que, el diseño se ha completado antes de la animación.
    • No es trabajo para mí en Swift 3 tampoco. Anima el primer tiempo, sin embargo, cuando me llaman 2º momento, es sólo un cambio sin la animación.
    • Yessssss … este trabajó como un encanto.
    • Creo que también podemos decir que la animación como.. animaciones:{self.imageView.imagen = auto.imageview.imagen}..es la misma cosa que creo que
    • Creo que también podemos decir que la animación como.. animaciones:{self.imageView.imagen = auto.imageview.imagen}..es la misma cosa que creo que

  3. 6

    Sí lo que dices es absolutamente correcto y esa es la manera de hacerlo. Escribí este método & utilizar siempre este a Desvanecerse en mi imagen. Estoy de acuerdo con CALayer para esto. Necesita importar Core Animation para esto.

    + (void)fadeInLayer:(CALayer *)l
    {
        CABasicAnimation *fadeInAnimate   = [CABasicAnimation animationWithKeyPath:@"opacity"];
        fadeInAnimate.duration            = 0.5;
        fadeInAnimate.repeatCount         = 1;
        fadeInAnimate.autoreverses        = NO;
        fadeInAnimate.fromValue           = [NSNumber numberWithFloat:0.0];
        fadeInAnimate.toValue             = [NSNumber numberWithFloat:1.0];
        fadeInAnimate.removedOnCompletion = YES;
        [l addAnimation:fadeInAnimate forKey:@"animateOpacity"];
        return;
    }

    Usted podría hacer lo contrario para el Fundido de salida de una imagen. Después se desvanece. Usted acaba de quitar de superview (que es UIImageView). [imageView removeFromSuperview].

    • Puedo añadir este código después de establecer una imagen en UIImageView, parece que hay es un parpadeo cuando la animación de inicio.
  4. 4

    También podría paquete de fade-in de funciones en una subclase, así que usted puede utilizarlo como un común UIImageView, como en el siguiente ejemplo:

    IMMFadeImageView *fiv=[[IMMFadeImageView alloc] initWithFrame:CGRectMake(10, 10, 50, 50)];
    [self.view addSubview:fiv];
    fiv.image=[UIImage imageNamed:@"initialImage.png"];
    fiv.image=[UIImage imageNamed:@"fadeinImage.png"];  //fades in

    Una posible implementación de la siguiente manera.

    Nota: la forma en que realmente se implemente el fade-in en el setImage: función puede cambiar, y podría ser uno de los otros excelentes ejemplos descritos en las otras respuestas a esta pregunta — la creación de un adicional sobre la marcha UIImageView como estoy haciendo aquí podría ser una inaceptable sobrecarga en su situación específica.

    IMMFadeImageView.h :

    #import <UIKit/UIKit.h>
    
    @interface IMMFadeImageView : UIImageView
    @property (nonatomic,assign) float fadeDuration;
    @end

    IMMFadeImageView.m :

    #import "IMMFadeImageView.h"
    
    @implementation IMMFadeImageView
    @synthesize fadeDuration;
    
    - (id)initWithFrame:(CGRect)frame
    {
        self = [super initWithFrame:frame];
        if (self) {
            self.fadeDuration=1;
        }
        return self;
    }
    -(void)setImage:(UIImage *)newImage{
    
        if(!self.image||self.fadeDuration<=0){
            super.image=newImage;
        } else {
            UIImageView *iv=[[UIImageView alloc] initWithFrame:self.bounds];
            iv.contentMode=self.contentMode;
            iv.image=super.image;
            iv.alpha=1;
            [self addSubview:iv];
            super.image=newImage;
            [UIView animateWithDuration:self.fadeDuration delay:0 options:UIViewAnimationCurveEaseInOut animations:^{
                iv.alpha=0;
            } completion:^(BOOL finished) {
                [iv removeFromSuperview];
            }];
        }
    }

    El código anterior se basa en algunos supuestos (incluyendo el ARCO está habilitado en su proyecto de XCode), sólo está pensado como una prueba de concepto, y en aras de la claridad y el enfoque, permanece relevante por la omisión de importantes relacionados de código. Por favor, no simplemente copiar-pegar ciegamente.

  5. 3

    Necesitaba la transición a repetir indefinidamente. Tomó una gran cantidad de ensayo y error para este, pero finalmente conseguí el resultado que estaba buscando. Estos son fragmentos de código para agregar una imagen de la animación a un UIImageView en un UITableViewCell.

    Aquí está el código correspondiente:

    @interface SomeViewController ()
    @property(nonatomic, strong) NSMutableArray *imagesArray;
    @property(nonatomic, assign) NSInteger varietyImageAnimationIndex;
    @property(nonatomic, assign) BOOL varietyImagesAnimated;
    @end
    
    @implementation SomeViewController
    @synthesize imagesArray;
    @synthesize varietyImageAnimationIndex;
    @synthesize varietyImagesAnimated;
    ...
    
    //NOTE: Initialize the array of images in perhaps viewDidLoad method.
    
    -(void)animateImages
    {
        varietyImageAnimationIndex++;
    
        [UIView transitionWithView:varietyImageView
                          duration:2.0f
                           options:UIViewAnimationOptionTransitionCrossDissolve
                        animations:^{
                            varietyImageView.image = [imagesArray objectAtIndex:varietyImageAnimationIndex % [imagesArray count]];
                        } completion:^(BOOL finished) {
                            [self animateImages];
                        }];
    }
    
    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    {
       ...
            [cell.imageView setImage:[imagesArray objectAtIndex:0]];
    
    
            [self setVarietyImageView:cell.imageView];
    
            if (! varietyImagesAnimated)
            {
                varietyImagesAnimated = YES;
                [self animateImages];
            }
    
        ...
        return cell;
    }
    • Hola me preguntaba si usted podría añadir algo más de información sobre su propia setVarietyImageView:la célula.imageView]; método como puedo conseguir la última celda para animar o todos a animar, pero muy rápido, Gracias
    • Hola Vab, «varietyImageView» es una referencia débil en el controlador de vista para que yo pueda asignar a la celda.imageView y referencia más adelante en el método ‘animateImages’. @property(nonatomic, débil) UIImageView *varietyImageView; puede hacer Que las imágenes rotar más rápido mediante el establecimiento de una más corta «duración» en «transitionWithView». Esperemos que esto es lo que están pidiendo.
    • Hola Christopher gracias por la respuesta, me preguntaba acerca de la «setVarietyImageView:» me asumir algún tipo de vacío, método que permite la reutilización como sólo he sido capaz de animar la última celda. De nuevo Gracias por responder, todo lo mejor del Vab
    • Este método es generado usando el estándar de la «propiedad» de la declaración. Por ejemplo, @property(nonatomic, débil) UIImageView *varietyImageView. Es un «débil» de referencia en lo que se refiere a otra variable local (el imageView de la celda de la tabla). Yo podría haber, en cambio, hizo una referencia a la celda de la tabla y el acceso de la célula.imageView en el método animateImages. Espero que esto ayude.
  6. 2

    Después de jugar con UIView.transition() y conseguir que los problemas con .transitionCrossDissolve opción (yo estaba tratando de animar imágenes cambiantes dentro de un UIImageView y la transición se produjo al instante, sin animación) me enteré de que sólo se necesita añadir una opción más, que es lo que permite animar las propiedades de cambio dentro de la visión (Swift 4.2):

    UIView.transition(with: self.imageView,
                       duration: 1,
                       options: [.allowAnimatedContent, .transitionCrossDissolve],
                       animations: { self.imageView.image = newImage },
                       completion: nil)

    Además: si usted tiene cualquier subvistas en el imageView, será a dibujar tan bien y podría prevenir la animación. Por ejemplo, yo tenía subvista con la falta de nitidez en mi imageView y que en caso de que la animación no funciona. Así que acabo de cambiar mi punto de vista de la jerarquía y mover desenfoque a su propio punto de vista y lo puso sobre imageView.

  7. 0

    Este es creo el camino mas corto de hacerlo. Crear una UIView animación y comprometerse en su imageView.

    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationDuration:0.5];
    [myImageView setAlpha:0.0];
    [UIView commitAnimations];
  8. 0

    Mediante el highlightedImage esta propiedad puede ser un poco más simple. He aquí un ejemplo en Swift 3. Primer set normal y resaltado de la imagen:

    let imageView = UIImageView(image: UIImage(named: "image"), highlightedImage: UIImage(named: "highlightedImage"))

    Y cuando desee cambiar entre los animados:

    UIView.transition(with: imageView, duration: 0.3, options: .transitionCrossDissolve, animations: { self.imageView.isHighlighted = !self.imageView.isHighlighted}, completion: .none)

Dejar respuesta

Please enter your comment!
Please enter your name here