1

アニメーション ブロックで 2 つのビューを交換するアクションを呼び出す barButtonItem があります。呼び出すアクション メソッドの先頭でを無効にbarButtonItemし、終了時に有効にして、ユーザーが反転が完了する前にビューを再度反転できないようにします。

これは UIView アニメーション ブロックで行われるため、メソッドのネッドで有効にすると、アニメーションが終了する前に有効になるため、瞬時に実行されて目的が失われます。

このメソッドでは、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

3 番目の引数 はcontext、 で設定された、選択したオブジェクトですbeginAnimations:context:。あなたが見逃しているのはbarButton、引数として使用してから、適切な署名でcontext書き直すことです。enableControlそのメソッドでは、3 番目の引数 を取り、それを からにcontextキャストします。void*UIBarButtonItem*

于 2009-08-03T19:24:44.113 に答える