UIAlertView, закрытый нажатием кнопки или NSTimer, приводит к ошибке на iPhone - PullRequest
0 голосов
/ 06 января 2012

Я программирую для iPhone.Я не программировал в течение двадцати лет, поэтому я довольно новичок в этом деле.У меня есть UIAlertView, который выскакивает, когда звук воспроизводится с AVAudioPlayer.Пользователь может закрыть UIAlertView, нажав кнопку или подождать, пока не закончится звук (отклоненный вызовом NSTimer).

Однако, если UIAlertView был закрыт кнопкой перед вызовом NSTimer, программа вылетает.Как проверить, отображается ли UIAlertView?

Я пробовал условие currentAlert.visible == YES, но это также дает сбой, если представление уже было отклонено.Каково значение объекта UIAlertView после его закрытия?

Вот код:

-(void) dismissAlert
{ 
     if(currentAlert.visible==YES){
     [currentAlert dismissWithClickedButtonIndex:0 animated:YES];
}


-(void) playSound:(NSString *)filename 
           volume:(float)volume 
           ofType:(NSString *)type 
         subtitle:(NSString *)text 
            speed:(float)speed 
            loops:(NSInteger)loops 
{
    //playSound
    NSString *path = [[NSBundle mainBundle] pathForResource:filename ofType:type];
    theAudio = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path]
                                                                             error:nil];
    theAudio.delegate = self;
    theAudio.volume=volume;
    theAudio.enableRate=YES;
    theAudio.rate=speed;
    theAudio.numberOfLoops=loops;
    [theAudio prepareToPlay];
    [theAudio play];

    //display alert
    if (text!=nil) {
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:nil 
                                                        message:text 
                                                       delegate:self  
                                              cancelButtonTitle:@"Close" 
                                              otherButtonTitles:nil];
        currentAlert=alert;
        [currentAlert show];
        duration= theAudio.duration/speed;
        [NSTimer    scheduledTimerWithTimeInterval:duration   
                                            target:self  
                                          selector:@selector(dismissAlert)    
                                          userInfo:nil 
                                           repeats:NO];
        [alert release];
    }

}

Спасибо.

Ответы [ 2 ]

0 голосов
/ 09 января 2012

Когда пользователь нажимает кнопку, на делегате UIAlertView вызывается метод alertView:didDismissWithButtonIndex:, поэтому вы должны выполнять свою работу

Сначала вам может понадобиться сохранить ссылку на таймер, чтобысоздайте новый ivar

// .h
@property (nonatomic, retain) NSTimer *alertViewTimer;

//.m
@synthesize alertViewTimer = _alertViewTimer;

- (void)dealloc;
{
    [_alertViewTimer release];
    //.. Release other ivars
    [super dealloc];
}

- (void)playSound:(NSString *)filename 
           volume:(float)volume 
           ofType:(NSString *)type  
         subtitle:(NSString *)text 
            speed:(float)speed 
            loops:(NSInteger)loops
{

// .. the rest of your method

self.alertViewTimer = [NSTimer scheduledTimerWithTimeInterval:duration
                                                       target:self
                                                     selector:@selector(dismissAlert)
                                                     userInfo:nil 
                                                      repeats:NO];

// .. the rest of your method

}

Затем в методе делегата реализуйте закрытие и аннулирование таймера:

- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex
{
    [alertViewTimer invalidate];
    self.alertViewTimer = nil;

    // .. Do whatever else you want to do.
}

, и вы можете оставить свой dismissAlert метод немного проще

- (void)dismissAlert
{ 
    [self.currentAlert dismissWithClickedButtonIndex:0 animated:YES];
}

Решение 2

Другой потенциальный способ сделать это - заменить это:

[NSTimer scheduledTimerWithTimeInterval:duration
                                 target:self
                               selector:@selector(dismissAlert)
                               userInfo:nil 
                                repeats:NO];

на:

[self performSelector:@selector(dismissAlert) withObject:nil afterDelay:duration];

и затем реализовать

- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex
{
    [NSObject cancelPreviousPerformRequestsWithTarget:self 
                                             selector:@selector(dismissAlert) 
                                               object:nil];

// .. Do whatever else you want to do.
}
0 голосов
/ 09 января 2012

Реализуйте этот метод, который будет вызываться, когда пользователь нажимает одну из кнопок в UIAlertView.

- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex {
    // user tapped a button, don't dismiss alert programatically (i.e. invalidate timer)
}

Документы: http://developer.apple.com/library/ios/#documentation/uikit/reference/UIAlertViewDelegate_Protocol/UIAlertViewDelegate/UIAlertViewDelegate.html#//apple_ref/occ/intfm/UIAlertViewDelegate/alertView:didDismissWithButtonIndex:

...