1

我有一个 barButtonItem 调用一个在动画块中交换两个视图的动作。我在它调用的操作方法的开头禁用了barButtonItem它,并且我想在它完成时启用它,以便用户在完成翻转之前不能再次翻转视图。

它在 UIView 动画块中执行此操作,因此如果我在方法的 ned 处启用它,它将是即时的,并且会破坏目的,因为它在动画完成之前被启用。

在该方法中,我将 sender 转换为 UIBarButtonItem,然后禁用它。所以我找到了[UIView setAnimationDidStopSelector:@selector()],但是我需要在选择器中传递我的 barButtonItem,这样 enableControl 方法才能启用它(如果我可以创建一个匿名函数,这会容易得多..)。

那么如何将 barButton 作为参数传递呢?我宁愿不必为此制作 ivar。这是代码:

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

这是我将其更改为的内容,但没有调用该方法..我做错了什么?

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

编辑:我想通了。我必须使按钮成为上下文,然后执行setAnimationDelegate:self,然后setAnimationDidEndSelector:@selector(myMethod:finished:context:),然后在方法中将上下文转换为uibarbuttonitem并重新启用它。

4

2 回答 2

3

我不认为您可以使用@selector 将多个参数传递给选择器,但是您可以将按钮设为类变量并像在选择器中那样启用或禁用它(而不是将其作为参数传递),以定义一个有多个参数的选择器,你可以使用 NSInvocation,像这样

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

但我认为这不适用于您正在尝试做的事情。

于 2009-08-03T19:19:36.447 回答
3

来自 UIView 的setAnimationDidStopSelector:文档:

选择器应采用以下形式:- (void)animationDidStop:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context.

第三个参数context是您选择的对象,设置在 中beginAnimations:context:。所以看起来你缺少的是barButton用作context参数,然后enableControl用适当的签名重写。在该方法中,您获取第三个参数 ,context并将其从void*转换为UIBarButtonItem*

于 2009-08-03T19:24:44.113 回答