Pregunta

Estoy tratando de voltear entre dos vistas. Eso es fácil, el código está debajo, pero también quiero voltear simultáneamente el botón utilizado para realizar el flip.

Puede ver este comportamiento en la aplicación iPod cuando reproduce una pista; Tocando el botón Flip voltea entre la portada y el listado de pistas, pero voltea el botón al mismo tiempo.

Esta es una página en el controlador de navegación, y el botón que quiero voltear es el rightBarButtonItem.

Aquí está el código que tengo hasta ahora. Esto voltea la vista, pero no la barra derecha.

[UIView setAnimationBeginsFromCurrentState: YES];
[UIView setAnimationDuration: 0.5f];
[UIView setAnimationCurve: UIViewAnimationCurveEaseInOut];
showingBackside = !showingBackside;
if (showingBackside) {
    [UIView setAnimationTransition: UIViewAnimationTransitionFlipFromLeft
                           forView: self.view
                             cache: YES];
    [self.view addSubview: backside.view];
    [frontside.view removeFromSuperview];
} else {
    [UIView setAnimationTransition: UIViewAnimationTransitionFlipFromRight
                           forView: self.view
                             cache: YES];
    [self.view addSubview: frontside.view];
    [backside.view removeFromSuperview];
}
// flip image, too
NSString *newImage = showingBackside ? @"backside.png" : @"frontside.png";
[(self.navigationItem.rightBarButtonItem) setImage: [UIImage imageNamed: newImage]];
[UIView commitAnimations];

(El código de volteo de imagen aquí puede no compilarlo; lo agregué después para tratar de explicar lo que estaba tratando de hacer).

Donde tengo problemas es que quiero cambiar el botón más a la derecha en el controlador de navegación para que voltee simultáneamente.

¿Cómo hago esto? ¿Qué visión animo, y lo hago como parte del mismo bloque de animación o como uno separado? Cualquier consejo sería apreciado, definitivamente aún no tengo un buen manejo de la animación.

¿Fue útil?

Solución

Hay alguna discusión aquí, pero la solución no es tan elegante.

En primer lugar, desde entonces UIBarButtonItem no es un descendiente de UIView, probablemente no puedas usar animaciones uikit directamente en el UIBarButtonItem. Sin embargo, puede intentar establecer un customView Y animando eso. Puedes usar el mismo bloque de animación.

Otros consejos

Bien, esto es lo que realmente hice para arreglar esto:

Ya estaba usando una vista de título personalizada. En lugar de usar rightBarButtonItem, Hice mi vista personalizada más amplia.

Creé una imagen de ambos lados del botón, completo con el marco de navegación y los incrusté en la aplicación. En mi vista de título, puse:

  • A UIView Ese será mi reemplazo para el control correcto (llámalo rightControl), posicionado apropiadamente.
  • Un botón sobre el UIView que responde a UIControlEventTouchUpInside y desencadena mi flipSide:.

En tiempo de ejecución creo un UIImageView para cada estado. Yo putboth UIImageViewpecado rightControl, pero esconde el que no es predeterminado. Cambio las banderas ocultas en flipSide: en un bloque de animación dedicado.

Increíblemente raro. Pero funciona.

Simplemente use un UIView personalizado para el botón de navegación correcto que contiene dos botones para voltear.

Puede usar un enfoque directo para crear una UIView personalizada que se muestra como el elemento del botón de navegación correcto. Este UIView debe contener los dos uibuttons entre los que desea voltear. ¡Recuerde que los uibuttons también son uiviews para que se puedan voltear usando las mismas transiciones con las que se puede voltear una vista de interfaz de usuario normal y, por supuesto, se pueden aprovechar! Aquí hay algún código de muestra que funciona:

Nota: Utilizo una función de conveniencia para crear botones como una categoría personalizada de UIViewController (nota: puede agregar este mismo código para crear una categoría personalizada para UIView también, simplemente copie las mismas líneas y reemplace UIViewController con UIView) - si desea Úselo también simplemente cree una categoría personalizada incluyendo este código a continuación, alternativamente, puede crear los Uibuttons como lo haría normalmente.

// create custom category for UIViewController to allow common button creation routine, add to .m or .mm file or add to a .h file and #import that .h file
        @interface UIViewController (ButtonAndSelector)
        - (UIButton *)createUIButtonWithImage:(UIImage *)image forState:(UIControlState)state withSelector:(SEL)selector usingFrame:(CGRect)buttonImageFrame;
        @end

        @implementation UIViewController (ButtonAndSelector)
        - (UIButton *)createUIButtonWithImage:(UIImage *)buttonImage forState:(UIControlState)state withSelector:(SEL)selector usingFrame:(CGRect)buttonImageFrame
        {
            UIButton *button = [[UIButton alloc]  initWithFrame:buttonImageFrame];
            [button setBackgroundImage:buttonImage forState:state];
            [button addTarget:self action:selector forControlEvents:UIControlEventTouchUpInside];
            [button setShowsTouchWhenHighlighted:YES];
            return button;
        }
        @end

// add this to your .h file:
        @property (strong, nonatomic) UIView *coverListView;
        @property (strong, nonatomic) UIButton *listButton;
        @property (strong, nonatomic) UIButton *coverButton;

        - (void)animateCoverListButtonFlip;

// add this to your .m or .mm file to synthesize the variables:
        @synthesize coverListView;
        @synthesize listButton;
        @synthesize coverButton;

// add this to your .m or .mm file in the viewDidLoad:

        // setup right button bar (flips between list icon and coverart image)
        self.coverListView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 32, 30)];
        self.coverListView.backgroundColor = [UIColor clearColor];
        self.coverListView.opaque = NO;

        self.listButton = [self createUIButtonWithImage:[UIImage imageNamed:@"navbar_icon_tracklisting"] forState:UIControlStateNormal withSelector:@selector(showHideQueue) usingFrame:CGRectMake(0, 0, 32, 30)];
        self.listButton.backgroundColor = [UIColor clearColor];
        self.listButton.showsTouchWhenHighlighted = NO;

        self.coverButton = [self createUIButtonWithImage:[UIImage imageNamed:@"default_coverart_small"] forState:UIControlStateNormal withSelector:@selector(showHideQueue) usingFrame:CGRectMake(0, 0, 32, 30)];
        [self.coverListView addSubview:self.coverButton]; // show coverButton by default
            self.coverButton.showsTouchWhenHighlighted = NO;

        UIBarButtonItem *barButtonItem = [[UIBarButtonItem alloc] initWithCustomView:self.coverListView];
        [self.navigationItem setRightBarButtonItem:barButtonItem];


// add this to viewDidAppear if you want to flip the button when the screen appears like the build in iPod app does
        [self animateCoverListButtonFlip];

// add this routine to flip the right navigation bar custom view / buttons
        - (void)animateCoverListButtonFlip
        {
            [UIView beginAnimations:nil context:NULL];
            [UIView setAnimationDuration:0.75];    
            [UIView setAnimationTransition:([self.listButton superview] ? UIViewAnimationTransitionFlipFromLeft : UIViewAnimationTransitionFlipFromRight) forView:self.coverListView cache:YES];

            if ([self.listButton superview]) {
                [self.listButton removeFromSuperview];
                [self.coverListView addSubview:self.coverButton];
            } else {
                [self.coverButton removeFromSuperview];
                [self.coverListView addSubview:self.listButton];
            }
            [UIView commitAnimations];
        }

// when the playing album cover changes, remember to update the coverButton:
        UIImage *artworkImage; // set this to the current playing album image
        [self.coverButton setImage:artworkImage forState:UIControlStateNormal]; 

// don't forget to call the animateCoverListButtonFlip in the button click handler (shown above as showHideQueue) that shows and hides the cover/queue(list of album tracks0 - something like this:

        - (void)showHideQueue
        {    
            [self animateCoverListButtonFlip];

            /* replace the code below that is commented out here with your own code that transitions between your cover view and your list view of album tracks, this code shows my transition and references views that are not part of this example/answer, but you don't need those - you'll have your own cover view (musicPlayerView) and list view (musicQueueView) to flip between.
            [UIView beginAnimations:nil context:NULL];
            [UIView setAnimationDuration:0.75];
            [UIView setAnimationTransition:([musicQueueView superview] ? UIViewAnimationTransitionFlipFromLeft : UIViewAnimationTransitionFlipFromRight) forView:self.contentView cache:YES];

            if ([musicQueueView superview]) { // if music queue is displayed
                [musicQueueView removeFromSuperview];
                [self.contentView addSubview:musicPlayerView];
            } else {
                [musicPlayerView removeFromSuperview];
                [self.contentView addSubview:musicQueueView];
                [[musicQueueView queueTableView] reloadData];
            }
            [UIView commitAnimations];*/
        }
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top