简体   繁体   中英

Run function while UIButton is pressed

I am building a remote control car using my iPhone as the controller.

I built a simple button as seen below:

-(void)moveArduinoForward
{
    UInt8 buf[3] = {0x01, 0x00, 0x00};
    buf[1] = 50;
    buf[2] = (int)num >> 8;
    NSData *data = [[NSData alloc] initWithBytes:buf length:3];
    [self.bleShield write:data];
}

-(void)stopArduino
{
    UInt8 buf[3] = {0x05, 0x00, 0x00};
    buf[1] = 50;
    buf[2] = (int)num >> 8;
    NSData *data = [[NSData alloc] initWithBytes:buf length:3];
    [self.bleShield write:data];
}



self.moveForwardButton  = [UIButton buttonWithType:UIButtonTypeCustom];
self.moveForwardButton.frame = CGRectMake(430.0, 175.0, 117.0, 133.0);
[self.moveForwardButton  setImage:[UIImage imageNamed:@"fwdUp.png"] forState:UIControlStateNormal];
[self.moveForwardButton  setImage:[UIImage imageNamed:@"fwdDown.png"] forState:UIControlStateHighlighted];
[self.moveForwardButton addTarget:self action:@selector(moveArduinoForward) forControlEvents:UIControlEventTouchDown];
[self.moveForwardButton addTarget:self action:@selector(stopArduino) forControlEvents:UIControlEventTouchUpInside | UIControlEventTouchUpOutside];
[self.view addSubview:self.moveForwardButton];

This currently doesn't work as I'd like. It only fires the moveArduinoForward event once, when the finger touches the button. I'd like it to continuously fire. I've tried multiple ways of doing this to no avail, any thoughts?

You can achieve this by using a timer.

Declare a timer in your .h or .m file like:

NSTimer *timer;

And implement your methods like:

// This method will be called when timer is fired
- (void)timerFired
{
    UInt8 buf[3] = {0x01, 0x00, 0x00};
    buf[1] = 50;
    buf[2] = (int)num >> 8;
    NSData *data = [[NSData alloc] initWithBytes:buf length:3];
    [self.bleShield write:data];
}

// This method schedules the timer
-(void)moveArduinoForward
{
    // You can change the time interval as you need
    timer = [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(timerFired) userInfo:nil repeats:YES];
}

// This method invalidates the timer, when you took your finger off from button
-(void)stopArduino
{
    [timer invalidate];
    timer = nil;
    UInt8 buf[3] = {0x05, 0x00, 0x00};
    buf[1] = 50;
    buf[2] = (int)num >> 8;
    NSData *data = [[NSData alloc] initWithBytes:buf length:3];
    [self.bleShield write:data];
}

A way to do this without a NSTimer would be to just get the method to call itself again if the button is still pressed. Using a timer might give you some jerky movement.

- (void)moveArduinoForward
{
    UInt8 buf[3] = {0x01, 0x00, 0x00};
    buf[1] = 50;
    buf[2] = (int)num >> 8;
    NSData *data = [[NSData alloc] initWithBytes:buf length:3];
    [self.bleShield write:data];

    if (self.moveForwardButton.isHighlighted) {
        [self moveArduinoForward];
    }
}

isHighlighted/isSelected. Can use either I suppose.

If you require a delay, you can replace the [self moveArduinoForward] line with [self performSelector:@selector(moveArduinoForward) withObject:nil afterDelay:1]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM