#iphone #objective-c #cocoa-touch #uibutton
#iPhone #objective-c #cocoa-touch #uibutton
Вопрос:
У меня есть представление, в котором у меня есть несколько больших кнопок, которые я настраиваю следующим образом:
SwipeButton* btn = [[[SwipeButton alloc] initWithFrame:CGRectMake(55, 0, 300, 50)] autorelease];
btn.tag = k;
[btn setBackgroundImage:[UIImage imageNamed:[NSString stringWithFormat:@"titleBackground.png"]]
forState:UIControlStateNormal];
[btn addTarget:self
action:@selector(indexAction:)
forControlEvents:UIControlEventTouchUpInside];
Я хотел бы иметь возможность либо касаться этих кнопок, а затем запускать метод indexAction, либо — если пролистывание было распознано — запускать другой метод.
Я думал, что создаю подкласс UIButton, чтобы в нем выполнялись пролистывания, но на самом деле это не решение, поскольку теперь распознаются как пролистывания, так и щелчки, поэтому срабатывают ОБА метода.
Есть ли способ обойти это? Как я могу расставить приоритеты при пролистывании и разрешить подкрашивание только в том случае, если НИКАКОГО ПОДКРАШИВАНИЯ не было?
Любая помощь была бы очень признательна.
Вот как я выделил подкласс UIButton:
#import "SwipeButton.h"
@implementation SwipeButton
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
[super touchesBegan:touches withEvent:event];
[self.superview touchesBegan:touches withEvent:event];
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
[super touchesMoved:touches withEvent:event];
[self.superview touchesMoved:touches withEvent:event];
}
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
[super touchesEnded:touches withEvent:event];
[self.superview touchesEnded:touches withEvent:event];
}
@end
Комментарии:
1. вы пробовали использовать класс UIGestureRecognizer ?
2. @Nick Weaver: Спасибо, Ник. Я не работал с UIGestureRecognizer, поскольку хотел настроить, какой длины должен быть свайп. Таким образом, я использую событие — (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *) … но я думаю, что нет никакого вреда и в использовании GestureRecognizer.
3. Почему голосование «против»? Наверное, это глупый вопрос, но на самом деле, я пытался хорошенько подумать над этим.
Ответ №1:
Я не думаю, что вам нужно создавать подкласс класса UIButton. Почему бы вам не попробовать что-то вроде этого:
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
UIImage *image = [UIImage imageNamed:@"picture_0.png"];
[button setImage:image forState:UIControlStateNormal];
[button setFrame:CGRectMake((applicationFrame.size.width - image.size.width)/2, applicationFrame.size.height/2, image.size.width, image.size.height)];
[button addTarget:self action:@selector(buttonTapped:) forControlEvents:UIControlEventTouchUpInside];
UISwipeGestureRecognizer *recognizer;
recognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleSwipeFrom:)];
[recognizer setDirection:UISwipeGestureRecognizerDirectionRight];
[recognizer setDelegate:self];
[[self view] addGestureRecognizer:recognizer];
[recognizer release];
recognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleSwipeFrom:)];
[recognizer setDirection:UISwipeGestureRecognizerDirectionLeft];
[recognizer setDelegate:self];
[[self view] addGestureRecognizer:recognizer];
[recognizer release];
Затем вы создаете методы для обработки нажатий и свайпов по кнопке:
// Prevent recognizing touches on the slider
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
if ([touch.view isKindOfClass:[UIButton class]]) {
return YES;
}
return NO;
}
-(void)handleSwipeFrom:(UISwipeGestureRecognizer *)recognizer {
if ([recognizer direction] == UISwipeGestureRecognizerDirectionLeft) {
// Handle left swipe
NSLog(@"left swipe");
} else {
// Handle right swipe
NSLog(@"right swipe");
}
}
- (void)buttonTapped:(id)sender {
NSLog(@"button pressed");
}
Первый из трех предыдущих методов объявлен в протоколе, поэтому не забудьте указать, что ваш класс реализует этот протокол:
@interface MyViewController : UIViewController <UIGestureRecognizerDelegate>
Это работает, я только что попробовал это сам. Надеюсь, это поможет! 😉
Комментарии:
1. Большое спасибо …! Действительно полезно. Я не думал о GestureRecognizer, поскольку использовал событие — (void)touchesEnded: (NSSet *)touches withEvent:(UIEvent *), чтобы определить длину свайпа (и настроить его в соответствии с моими потребностями). Но, очевидно, я думаю, нет ничего плохого в использовании обоих…
2. Работает как по волшебству … так что еще раз спасибо. Но я действительно не знаю, как настроить минимальное значение. требуемая длина пролистывания. В идеале я хотел бы установить его равным 10 пикселям, а отклонение — 15 пикселям, но я не вижу способа сделать это с помощью UIGestureRecognizer.
3. Вы не можете установить минимальную длину пролистывания при использовании UISwipeGestureRecognizer. Зачем вам вообще это нужно?
4. Я бы хотел, чтобы свайп был очень отзывчивым. Возьмем, к примеру, приложение photos. Если вы проведете пальцем совсем немного (около 5 пикселей), изображение переместится. Если вы хотите получить немедленную обратную связь, я думаю, было бы очень полезно настроить требуемую длину пролистывания. У меня есть такой метод, но, как я уже сказал, я использую touchesEnded, а затем измеряю разницу между начальной и конечной точками касания — таким образом, определяя, был ли достигнут порог требуемой длины пролистывания.
Ответ №2:
Взгляните на UIGestureRecognizer
документацию и связанные с ней примеры (например).