iOS: 如何在 super class 中正确实现自定义手势识别?

iOS: How to correctly implement custom gesture recognizer in super class?

我的 iOS8+ 应用程序中的按钮应该通过在按钮周围绘制轮廓来做出反应,只要用户按下手指即可。目标是将此行为封装到 OutlineButton class 中(cp. below class hierarchy)。松开手指时,应用程序应执行定义的操作(主要是执行到另一个视图控制器的 segue)。为此,这是我当前的 class 层次结构:

 - UIButton
  |_ OutlineButton
    |_ FlipButton

FlipButton class 执行一些奇特的翻转效果,另外我在 UIView 上有一个类别用于投影、圆角和轮廓。

目前我有以下额外的class:

#import <UIKit/UIKit.h>

@interface TouchDownGestureRecognizer : UIGestureRecognizer

@end

...以及相应的实现:

#import "UIView+Extension.h"
#import "TouchDownGestureRecognizer.h"

@implementation TouchDownGestureRecognizer

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
    [self.view showOutline]; // this is a function in the UIView category (cp. next code section)
}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
    [self.view hideOutline]; // this is a function in the UIView category (cp. next code section)
}

@end

...这是 UIView+Extension.m 类别的相关片段,用于在按钮上绘制轮廓:

- (void)showOutline {
    self.layer.borderColor = [UIColor whiteColor].CGColor;
    self.layer.borderWidth = 1.0f;
}

- (void)hideOutline {
    self.layer.borderColor = [UIColor clearColor].CGColor;
}

... 并且在 OutlineButton.m 文件中我有以下内容:

#import "OutlineButton.h"

@implementation OutlineButton

- (id)initWithCoder:(NSCoder*)aDecoder {
    self = [super initWithCoder:aDecoder];
    if (self) {
        [self addGestureRecognizer:[[TouchDownGestureRecognizer alloc] init]];
    }
    return self;
}

@end

从视觉上看,这工作正常,只要触摸一个按钮,就会绘制一个轮廓,一旦松开手指,轮廓就会再次隐藏。但是通过故事板连接到这些按钮的 IBAction 和 segues 是在一个巨大的延迟(大约 2 秒)之后执行的(如果有的话)。如果多次按下按钮(......经过长时间延迟),这些操作也会执行多次。真是奇怪的行为...

有人知道如何解决这个问题吗?

解决方案(基于马特的回答,谢谢):

#import "OutlineButton.h"
#import "UIView+Extension.h"

@implementation OutlineButton

- (id)initWithCoder:(NSCoder*)aDecoder {
    self = [super initWithCoder:aDecoder];
    if (self) {
        [self addTarget:self action:@selector(showOutline) forControlEvents:UIControlEventTouchDown];
        [self addTarget:self action:@selector(hideOutline) forControlEvents:UIControlEventTouchUpInside | UIControlEventTouchUpOutside];
    }
    return self;
}

@end

the buttons in my iOS8+ app should react by painting an outline around the buttons as long as the user presses the finger on it

最符合框架的实现方式是为突出显示状态的按钮分配一个具有轮廓的图像。按下按钮时,它会被突出显示;因此,只有在按下按钮时才会显示轮廓。