Добавление NSTimer к кнопке - PullRequest
0 голосов
/ 29 марта 2012

Я искал по всему Интернету, и мне не повезло, что этот проект работал с таймером. Я получаю аварийное приложение каждый раз, когда использую таймер.

Для тестирования и обучения я создаю маленькие простые приложения. Это кнопка, которая посылает ракету из нижней части экрана и исчезает с экрана вместе со звуковым эффектом ракеты.

Я хочу добавить таймер к кнопке, чтобы при удерживании кнопки ракета запускалась, сбрасывалась и запускалась снова и снова, пока я не отпущу кнопку. Я думаю, что теперь моя единственная надежда - вставить код из моих файлов .h & .m, и, надеюсь, кто-то может сказать мне, что мне нужно сделать и где нужно добавить надлежащий код для этого проекта.

Большое спасибо за помощь, она очень ценится.

.H ФАЙЛ:

//  MVViewController.h
#import <UIKit/UIKit.h>
#import <AVFoundation/AVFoundation.h>

@interface MVViewController : UIViewController

@property (strong, nonatomic) IBOutlet UIImageView *moveMe2;

//New action to repeat launch (Touch Down)
- (IBAction)rocketRepeat:(id)sender;

//New action to stop launch (Touch Up Inside)
- (IBAction)rocketStop:(id)sender;

//This is the original launch button (Touch Down)
- (IBAction)yourRocketButton:(id)sender; 

@end

.M ФАЙЛ

//  MVViewController.m

#import "MVViewController.h"

@interface MVViewController ()

@end

@implementation MVViewController {
    AVAudioPlayer *audioPlayer;
}

@synthesize moveMe2;

- (void)viewDidLoad
{
    [super viewDidLoad];
}

- (void)viewDidUnload
{
    [self setMoveMe2:nil];
    [super viewDidUnload];
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return ((interfaceOrientation == UIInterfaceOrientationPortrait) || (interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown));
}

- (IBAction)rocketRepeat:(id)sender
//Getting error "Use of undeclared identifier 'yourRocketButton'
{
    [yourRocketButton addTarget:self action:@selector(rocketRepeat:) forControlEvents:UIControlEventTouchDown];
}

- (IBAction)rocketStop:(id)sender 
//Getting error "Use of undeclared identifier 'yourRocketButton'
{
    [yourRocketButton addTarget:self action:@selector(rocketStop:) forControlEvents:UIControlEventTouchUpInside];
}

- (IBAction)yourRocketButton:(id)sender {
    moveMe2.center = CGPointMake(100.0f, 408.0f);
    [UIView animateWithDuration:2.0 animations:^{moveMe2.center = CGPointMake(100, -55);}]; 
}

@end

@@@@@@@@

РЕДАКТИРОВАТЬ * Это то, что, наконец, сработало *

//  RKViewController.m

#import "RKViewController.h"

@interface RKViewController ()

@end

@implementation RKViewController
@synthesize RocketMove;
@synthesize Launch;

- (void)viewDidLoad
{
    [super viewDidLoad];
}

- (void)viewDidUnload
{
    [self setRocketMove:nil];
    [self setLaunch:nil];
    [super viewDidUnload];
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return ((interfaceOrientation == UIInterfaceOrientationPortrait) || (interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown));
}

- (IBAction)rocketRepeat:(id)sender {
    [self performSelector:@selector(rocketRepeat:) withObject:self afterDelay:1.0];
    RocketMove.center = CGPointMake(100.0f, 408.0f);
    [UIView animateWithDuration:1.0 animations:^{RocketMove.center = CGPointMake(100, -55);}];
}

- (IBAction)rocketStop:(id)sender {
    [NSObject cancelPreviousPerformRequestsWithTarget:self];
}
@end

//  RKViewController.h

#import <UIKit/UIKit.h>

@interface RKViewController : UIViewController

@property (strong, nonatomic) IBOutlet UIImageView *RocketMove;
@property (strong, nonatomic) IBOutlet UIButton *Launch;

- (IBAction)rocketRepeat:(id)sender;
- (IBAction)rocketStop:(id)sender;
@end

Ответы [ 2 ]

1 голос
/ 29 марта 2012

Если вы хотите, чтобы ракеты запускались автоматически после нажатия кнопки, вы должны добавить следующий код в ваш метод rocketLaunch :. Если вы хотите, чтобы они начали появляться с самого начала, вызовите это из вашего метода viewDidLoad.

- (void)launchRocketsTimer
{
    [self.timer invalidate]; //you have to create a NSTimer property to your view controller
    self.timer = [NSTimer scheduledTimerWithTimeInterval:2.5 target:self selector:@selector(scheduledRocketLaunch:) userInfo:nil repeats:YES];
}

- (void)scheduledRocketLaunch:(NSTimer *)t
{
    moveme2.center = _bottom_point_; //set it where you would like it to start
    [UIView animateWithDuration:2.0 animations:^{moveMe2.center = CGPointMake(100, -55);}];
}

Не забудьте освободить свой таймер в dealloc.

О, и еще одна вещь: У вас есть утечка памяти на вашем rocketsound: методе, когда вы выделяете AVAudioPlayer. Вы можете заменить код на этот:

- (IBAction)rocketsound:(id)sender
 {
    NSURL *url = [NSURL fileURLWithPath: [NSString stringWithFormat:@"%@/rocketlaunch.mp3", [[NSBundle mainBundle] resourcePath]]];

    NSError *error;
    if (self.audioPlayer == nil)
    {
        self.audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:&error] autorelease]; //Note the use of setter property and the autorelease. (you could use your own code because the if will prevent the leak in this case).
    }

    audioPlayer.numberOfLoops = 0;

    if (audioPlayer == nil)
        NSLog(@"%@", [error description]);
    else 
        [audioPlayer play];
}
1 голос
/ 29 марта 2012

Вы должны использовать UIControlEvent для этой цели.

1. Вам нужно два отдельных IBAction для каждой цели, скажем, один для удержания кнопки, один после отпускания кнопки.

2. Для удержания кнопки необходимо использовать UIControlEventTouchDown. Поэтому выполните действие rocketRepeat, в котором вы продолжаете вызывать действие ракеты, используя NSTimer с регулярными интервалами, и используйте:

 [yourRocketButton addTarget:self action:@selector(rocketRepeat:) forControlEvents:UIControlEventTouchDown];

3. Затем используйте другое действие с UIControlEventTouchUpInside, где вы аннулируете NSTimer, чтобы ракета остановилась. Назовите это действие rocketStop или что-то еще и используйте:

[yourRocketButton addTarget:self action:@selector(rocketStop:) forControlEvents:UIControlEventTouchUpInside];

--- EDIT ---

Действие 1:

- (IBAction)rocketRepeat:(id)sender
{
    //code for starting rocker, timer action
}

Действие 2:

- (IBAction)rocketStop:(id)sender
{
   //Code for stopping rocket
}

yourButton - это не действие, а кнопка UIB. Я надеюсь, что вы создали кнопку в IB, перетащите кнопку. И в viewDidLoad вы пишете эти 2 строки кода:

Вместо yourButton вы пишете название кнопки, которую вы перетащили, упавшей из IB. Я надеюсь, что вы знаете, как добавить кнопку из конструктора интерфейса и подключить ее.

- (void)viewDidLoad
{
  [yourRocketButton addTarget:self action:@selector(rocketRepeat:) forControlEvents:UIControlEventTouchDown]; //For touch down button action
  [yourRocketButton addTarget:self action:@selector(rocketStop:) forControlEvents:UIControlEventTouchUpInside]; //When button is let go.

    [super viewDidLoad];


   // Do any additional setup after loading the view, typically from a nib.
}
...