Как использовать два разных метода для ПРОЛИСТЫВАНИЯ по кнопке и подкраски?

#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 документацию и связанные с ней примеры (например).