【问题标题】:UIButton press and hold - repeat action until let goUIButton 按住 - 重复动作直到松开
【发布时间】:2013-05-13 00:05:29
【问题描述】:

只要某人的手指按下按钮,我就想让某个方法运行并重复自身。当手指不在按钮上时,我希望该方法停止重复

有没有办法在方法实现过程中检查 touchDown 是否仍然发生?救命!

【问题讨论】:

标签: ios uibutton


【解决方案1】:

您可以使用UIControlEventTouchDown 控制事件来启动方法运行,并使用UIControlEventTouchUpInside 或类似方法来检测按钮何时不再被“按下”。

设置按钮的动作,例如:

[myButton addTarget:self action:@selector(startButtonTouch:) forControlEvents:UIControlEventTouchDown];
[myButton addTarget:self action:@selector(endButtonTouch:) forControlEvents:UIControlEventTouchUpInside | UIControlEventTouchUpOutside];

(注意上面会导致按钮内外的touch up调用endButtonTouch:方法。)

然后添加startButtonTouch:endButtonTouch 方法,例如:

- (void)startButtonTouch:(id)sender {
    // start the process running...
}

- (void)endButtonTouch:(id)sender {
// stop the running process...
}

【讨论】:

  • 如果用户点击按钮并将手指移到按钮边界之外,此方法将不起作用。
  • 同时使用UIControlEventTouchUpInsideUIControlEventTouchUpOutside。添加到答案中。如果您想在用户拖动按钮时结束它,请添加UIControlEventTouchDragExit
【解决方案2】:

根据 bobnoble 的回答,这是一个辅助视图

#import <UIKit/UIKit.h>

@interface YOIDCAutorepeatingButton : UIButton

// you COULD pinch pennies switching to nonatomic, but consider
// how much time it would take to debug if some day some moron decides without checking this spec
// to alter this prop off another thread
@property (atomic) NSTimeInterval delayUntilAutorepeatBegins;
@property NSTimeInterval delayBetweenPresses;

@property (weak) id<NSObject> recipient;
@property SEL touchActionOnRecipient;

@end

----------> .m

#import "YOIDCAutorepeatingButton.h"

@interface YOIDCAutorepeatingButton()
{
NSTimeInterval _pressStartedAt;
}

@end

@implementation YOIDCAutorepeatingButton


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

    self.delayUntilAutorepeatBegins = .250;
    self.delayBetweenPresses = .080;
}
return self;
}

-(void)killLastCharacter:(id)sender
{
[self.recipient performSelector:self.touchActionOnRecipient withObject:sender];
}

- (void)performAutorepeat:(id)sender
{
if(!self.delayBetweenPresses) {
    // bail
    return;
}
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(self.delayBetweenPresses * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
    if(_pressStartedAt) {
        [self killLastCharacter:sender];
        [self performAutorepeat:sender];
    }
});
}

- (void)startButtonTouch:(id)sender {

[self killLastCharacter:sender];
NSTimeInterval now = [NSDate timeIntervalSinceReferenceDate];
_pressStartedAt = now;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(self.delayUntilAutorepeatBegins * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
    if(_pressStartedAt) {
        [self killLastCharacter:sender];
        [self performAutorepeat:sender];
    }
});
}

- (void)endButtonTouch:(id)sender {
_pressStartedAt = 0;
}

@end

-------- 示例用法-------

- (IBAction)killLastDigit:(id)sender {

.....

- (void)viewDidLoad
{
assert(self.backSpace);
[YOIDCAutorepeatingButton class]; // if xib is in a bundle other than main gottal load the class
// otherwise you'd get -[UIButton setRecipient:]: unrecognized selector sent to instance
// on setRecipient:
self.backSpace.recipient = self;
self.backSpace.touchActionOnRecipient = @selector(killLastDigit:);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-17
    • 2011-06-16
    相关资源
    最近更新 更多