Передача аргументов в селектор в IPhone - PullRequest
1 голос
/ 03 августа 2009

У меня есть barButtonItem, который вызывает действие, которое меняет два представления в анимационном блоке. Я отключаю barButtonItem в начале метода действия, которое он вызывает, и хочу включить его по завершении, чтобы пользователь не мог перевернуть представление еще раз, пока оно не перевернуло.

Он делает это в анимационном блоке UIView, так что, если я включу его в ned метода, это будет мгновенно, и это разрушит цель, потому что она будет активирована до завершения анимации.

В этом методе я преобразую отправителя в UIBarButtonItem и отключаю его. Итак, я нашел [UIView setAnimationDidStopSelector:@selector()], но мне нужно передать свой barButtonItem в селектор, чтобы метод enableControl включил это (это было бы намного проще, если бы я мог сделать анонимную функцию ..).

Так как я могу передать barButton в качестве аргумента? Я бы предпочел не делать ивар только для этого .. Вот код:

- (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 и снова включить его.

Ответы [ 2 ]

3 голосов
/ 03 августа 2009

Из документов UIView setAnimationDidStopSelector::

Селектор должен иметь форму: - (void)animationDidStop:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context.

Третий аргумент context - это объект по вашему выбору, установленный в beginAnimations:context:. Поэтому кажется, что вам не хватает использовать barButton в качестве аргумента context, а затем переписать enableControl с правильной подписью. В этом методе вы берете третий аргумент context и преобразуете его из void* в UIBarButtonItem*.

3 голосов
/ 03 августа 2009

Я не думаю, что вы можете передать более одного аргумента селектору с помощью @selector, однако вы можете сделать свою кнопку переменной класса и включить или отключить ее в селекторе (вместо того, чтобы передавать в качестве аргумента) , чтобы определить селектор с несколькими аргументами, вы можете использовать NSInvocation, например,

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

Но я не думаю, что это сработает для того, что вы пытаетесь сделать.

...