Pregunta

Tengo un barButtonItem que llama a una acción que intercambia dos vistas en un bloque de animación. Inhabilito el barButtonItem al comienzo del método de acción al que llama, y ??quiero habilitarlo cuando finalice, para que el usuario no pueda voltear la vista nuevamente antes de que haya terminado de voltear.

Hace esto en un bloque de animación UIView, por lo que si lo habilito en el ned del método, será instantáneo y eso destruye el propósito porque se habilita antes de que finalice la animación.

En el método, envío el remitente a un UIBarButtonItem y lo deshabilito. Así que encontré [UIView setAnimationDidStopSelector: @selector ()] , pero necesito pasar mi barButtonItem en el selector para que el Método enableControl lo permita (esto sería mucho más fácil si pudiera hacer un anónimo función..).

Entonces, ¿cómo puedo pasar el barButton como argumento? Prefiero no tener que hacer un ivar solo por esto ... Aquí está el código:

- (void)barBtnItemSwitchViews_Clicked:(id)sender {
    UIBarButtonItem *barButton = (UIBarButtonItem *)sender;
    barButton.enabled = NO;
    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationDuration:0.8];
    [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
    if(!self.yellowVC.view.superview) {
        [UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:innerView cache:YES];
        [yellowVC viewWillAppear:YES];
        [blueVC viewWillDisappear:YES];
        [blueVC.view removeFromSuperview];
        self.blueVC = nil;
        [innerView addSubview:yellowVC.view];
    } else if(!self.blueVC.view.superview) {
        [UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:innerView cache:YES];
        [blueVC viewWillAppear:YES];
        [yellowVC viewWillDisappear:YES];
        [yellowVC.view removeFromSuperview];
        self.yellowVC = nil;
        [innerView addSubview:blueVC.view];
    }
    [UIView commitAnimations];
    [UIView setAnimationDidStopSelector:@selector(enableControl:)]; // How do I pass barButton??
}

- (void)enableControl:(UIControl *)control {
    control.enabled = YES;
}

Esto es a lo que lo cambié, pero el método no se llama ... ¿Qué estoy haciendo mal?

- (void)barBtnItemSwitchViews_Clicked:(id)sender {
    UIBarButtonItem *barButton = (UIBarButtonItem *)sender;
    barButton.enabled = NO;
    [UIView beginAnimations:nil context:barButton];
    [UIView setAnimationDuration:0.8];
    [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
    if(!self.yellowVC.view.superview) {
        [UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:innerView cache:YES];
        [yellowVC viewWillAppear:YES];
        [blueVC viewWillDisappear:YES];
        [blueVC.view removeFromSuperview];
        self.blueVC = nil;
        [innerView addSubview:yellowVC.view];
    } else if(!self.blueVC.view.superview) {
        [UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:innerView cache:YES];
        [blueVC viewWillAppear:YES];
        [yellowVC viewWillDisappear:YES];
        [yellowVC.view removeFromSuperview];
        self.yellowVC = nil;
        [innerView addSubview:blueVC.view];
    }
    [UIView setAnimationDidStopSelector:@selector(flipViewAnimationDidStop:finished:context:)];
    [UIView commitAnimations];
}

- (void)flipViewAnimationDidStop:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context {
    UIBarButtonItem *barButton = (UIBarButtonItem *)context;
    barButton.enabled = NO;
    NSLog(@"Disabled");
}

EDITAR: lo descubrí. Tenía que hacer que el botón fuera el contexto, y luego hacer setAnimationDelegate: self , y luego setAnimationDidEndSelector: @selector (myMethod: terminado: contexto :) , y luego en el método transmitir contexto a uibarbuttonitem y volver a habilitarlo.

¿Fue útil?

Solución

Del setAnimationDidStopSelector de UIView: docs:

  

El selector debe tener la forma: - (void) animationDidStop: (NSString *) animationID terminado: (NSNumber *) contexto terminado: (void *) contexto .

El tercer argumento, context , es un objeto de su elección, establecido en beginAnimations: context: . Parece que lo que falta es usar barButton como argumento context y luego reescribir enableControl con una firma adecuada. En ese método, toma el tercer argumento, context , y lo convierte de void * a un UIBarButtonItem * .

Otros consejos

No creo que pueda pasar más de un argumento al selector utilizando @selector, sin embargo, podría hacer que su botón sea una variable de clase y habilitarlo o deshabilitarlo así en el selector (en lugar de pasarlo como argumento) , para definir un selector con múltiples argumentos, puede usar NSInvocation, como así

NSInvocation *inv = [[NSInvocation alloc] init];
[inv setSelector:@selector(foo:bar:)];
[inv setArgument:123 atIndex:0];
[inv setArgument:456 atIndex:1];

Pero no creo que esto funcione para lo que intentas hacer.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top