在 iPhone 中的选择器中传递参数

发布于 2024-07-30 05:13:45 字数 3288 浏览 3 评论 0原文

我有一个 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 并重新启用它。

I have a barButtonItem that calls an action which swaps two views in an animation block. I disable the barButtonItem at the beginning of the action method that it calls, and the I want to enable it when its finished, so that the user can't flip the view again before it has finished flipping.

It does this in a UIView animation block, so If I enable it at the ned of the method, it will be instant and that destroys the purpose because it gets enabled before the animation finishes.

In the method, I cast sender to a UIBarButtonItem, and I disable that. So I found [UIView setAnimationDidStopSelector:@selector()], but I need to pass my barButtonItem in the selector so the enableControl Method will enable that (this would be a lot easier if I could make an anonymous function..).

So how can I pass the barButton as an argument? I'd rather not have to make an ivar just for this.. Here's the code:

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

Here's what I changed it to, but the method isn't being called.. What am I doing wrong?

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

EDIT: I figured it out. I had to make the button the context, and then do setAnimationDelegate:self, and then setAnimationDidEndSelector:@selector(myMethod:finished:context:), and then in the method cast context to uibarbuttonitem and re-enable it.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

万劫不复 2024-08-06 05:13:46

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

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

,但我认为这不适用于您想要做的事情。

I dont think you can pass more than one argument to the selector by using @selector, however you could make your button a class variable and enable or disable it like that in the selector (instead of it being passed as an argument), to define a selector with multiple arguments you can use NSInvocation, like so

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

But I dont think this will work for what you are trying to do.

又怨 2024-08-06 05:13:45

来自 UIView 的 setAnimationDidStopSelector: 文档:

选择器的格式应为:- (void)animationDidStop:(NSString *)animationID finish:(NSNumber *)finished context:(void *)context

第三个参数 context 是您选择的对象,在 beginAnimations:context: 中设置。 因此,您似乎缺少的是使用 barButton 作为 context 参数,然后使用正确的签名重写 enableControl 。 在该方法中,您采用第三个参数 context,并将其从 void* 转换为 UIBarButtonItem*

From UIView's setAnimationDidStopSelector: docs:

The selector should be of the form: - (void)animationDidStop:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context.

The third argument, context, is an object of your choice, set in beginAnimations:context:. So it seems like what you're missing is to use barButton as the context argument, and then rewrite enableControl with a proper signature. In that method, you take the third argument, context, and cast it from void* to a UIBarButtonItem*.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文