问题
I've got four simple methods, four buttons and one object.
- (IBAction)left:(id)sender{
object.center = CGPointMake(object.center.x - 5, object.center.y);
}
- (IBAction)right:(id)sender{
object.center = CGPointMake(object.center.x + 5, object.center.y);
}
- (IBAction)down:(id)sender{
object.center = CGPointMake(object.center.x, object.center.y + 5);
}
- (IBAction)up:(id)sender{
object.center = CGPointMake(object.center.x, object.center.y - 5);
}
When I press a button, the method is executed once. When the button is pressed continuously it's the same. What do I have to do so that when I press the button continuously my object keep moving to the left?
回答1:
As @Maudicus said, you probably need to do something with NSTimer
s to get a continuous button press triggering. The example I'm going to use is moving an object on screen (since you want to do that anyway). I've used graded moving because I have no idea whether you are writing a grid-based game and so need exactly 5 pixels of movement. Just cut out all of the stepSize code and set it to 5 if that's what you do.
Write a timer callback function which checks whether a
BOOL
is set and if so keeps triggering itself:- (void)moveObjectLeft:(NSTimer *)timer { // check the total move offset and/or the X location of the object here // if the object can't be moved further left then invalidate the timer // you don't need to check whether the button is still being pressed //[timer invalidate]; //return; // the object moves gradually faster as you hold the button down for longer NSNumber *moveOffset = (NSNumber *)[timer userInfo]; NSUInteger stepSize = 1; if(moveOffset >= 40) stepSize = 10; else if(moveOffset >= 15) stepSize = 5; else if(moveOffset >= 5) stepSize = 2; // move the object object.center = CGPointMake(object.center.x - stepSize, object.center.y); // store the new total move offset for this press moveOffset += stepSize; [timer setUserInfo:moveOffset]; }
Create a timer property in the current classes
.h
:@property (nonatomic, retain) NSTimer *moveTimer;
Synthesize it in your
.m
:@synthesize moveTimer;
Create your timer object when the button is pressed. Either do this in
touchesBegan:withEvent:
and check it's a Touch Down event, or connect the Touch Down event in Interface Builder to anIBAction
method.NSNumber *moveOffset = [NSNumber numberWithUnsignedInt:0]; self.moveTimer = [NSTimer scheduledTimerWithTimeInterval:0.2 target:self selector:@selector(moveObject:) userInfo:moveOffset repeats:YES];
When the button is released (using one of the above methods again,
touchesEnded:withEvent:
for a Touch Up Inside or probably even a Touch Up Outside, or anotherIBAction
on both of those events), invalidate the timer externally:[self.moveTimer invalidate]; self.moveTimer = nil;
回答2:
When a button gives its mousedown event, start moving. When the button gives its mouseup event, stop moving.
Be careful; this can act funny if multiple buttons can be pressed at the same time.
回答3:
I think you need to schedule a timer and repeat a method that checks the button states.
// assume timer is set up to test button states, triggering controlLoop
every x seconds
-(void)controlsLoop
{
if (leftButton.state == UIControlStateSelected || leftButton.state == UIControlStateHighlighted) {
}
}
I have never done this before so have fun playing around with it. I usually achieve controls like you want in Cocos2d,
It might be better to implement these methods
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
to set which direction you want to move the object, and still have a timer triggering the actual movement.
来源:https://stackoverflow.com/questions/8248768/how-to-repeatedly-perform-an-action-when-a-button-is-continuously-pressed-in-obj