Передача аргументов в селектор в IPhone
-
11-07-2019 - |
Вопрос
У меня есть 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: законченный: context:)
, а затем в методе приведите контекст к uibarbuttonitem
и включите его снова. Р>
Решение
Из документа setAnimationDidStopSelector:
в UIView:
Селектор должен иметь форму:
- (void) animationDidStop: (NSString *) animationID закончен: (NSNumber *) закончен контекст: (void *) контекст
. Р>
Третий аргумент context
- это объект по вашему выбору, установленный в beginAnimations: context:
. Поэтому кажется, что вам не хватает использовать barButton
в качестве аргумента context
, а затем переписать enableControl
с правильной подписью. В этом методе вы берете третий аргумент context
и преобразуете его из void *
в UIBarButtonItem *
.
Другие советы
Я не думаю, что вы можете передать более одного аргумента селектору с помощью @selector, однако вы можете сделать свою кнопку переменной класса и включить или отключить ее в селекторе (вместо того, чтобы передавать в качестве аргумента) , чтобы определить селектор с несколькими аргументами, вы можете использовать NSInvocation, например, так
NSInvocation *inv = [[NSInvocation alloc] init];
[inv setSelector:@selector(foo:bar:)];
[inv setArgument:123 atIndex:0];
[inv setArgument:456 atIndex:1];
Но я не думаю, что это сработает для того, что вы пытаетесь сделать.