user1118684
user1118684

Reputation: 244

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?

Upvotes: 0

Views: 137

Answers (2)

Beau Nouvelle
Beau Nouvelle

Reputation: 7252

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]

Upvotes: 0

Midhun MP
Midhun MP

Reputation: 107121

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];
}

Upvotes: 1

Related Questions