应用程序唤醒后,在UINavigationController堆栈上复制UIViewControllers

时间:2013-05-23 10:26:12

标签: ios objective-c uinavigationcontroller mkmapview

我刚刚学习了IOS编程,正在编写我的第一个iPhone应用程序。

我的应用程序提供有关MKMapView的信息,其视图控制器是UINavigationController的根视图控制器。如果移动信号不好,我使用mapViewDidFailLoadingMap:withError:使应用程序将两个不同视图控制器中的一个推送到导航控制器堆栈,具体取决于用户正在做什么。代码如下:

    - (void)mapViewDidFailLoadingMap:(MKMapView *)mapView withError:(NSError *)error
    {
        NSLog(@"mapViewDidFailLoadingMap: %@", [error localizedDescription]);
        [aiView stopAnimating];

        if (mapTypeInt == 0) {
            NSString *message = 
    [NSString stringWithFormat:@"Your signal is not currently 
     strong enough to download a map. Switching to table view."];
            UIAlertView *av = [[UIAlertView alloc] initWithTitle:@"Maps Unavailable"
                                                         message:message
                                                        delegate:nil
                                               cancelButtonTitle:@"OK"
                                               otherButtonTitles:nil];
            [av show];
            if (currentMode == @"retracingSteps")
            {
                RetraceViewController *rvc = 
    [[RetraceViewController alloc] initWithNibName:@"RetraceViewController" bundle:nil];
                [[self navigationController] pushViewController:rvc animated:YES];
            }
            else{
                TripTableViewController *ttvc = [[TripTableViewController alloc] init];
                [[self navigationController] pushViewController:ttvc animated:YES];
            }
        }
        else{
            [self setMapType:0];

            NSString *message = [NSString stringWithFormat:
    @"Your signal is not currently strong enough to download a satellite map. 
    Switching to Standard Map view."];
            UIAlertView *av = [[UIAlertView alloc] initWithTitle:@"Can't Use Satellite Maps"
                                                         message:message
                                                        delegate:nil
                                               cancelButtonTitle:@"OK"
                                               otherButtonTitles:nil];
            [av show];
        }



    }

昨天我测试了乡村山谷中可怜的移动信号,并将正确的第二视图控制器推到了堆栈上。当我锁定手机并在几分钟后重新检查应用程序时,我注意到的是醒来时,根视图控制器快速显示,然后是我预期的视图控制器。实际上,这样做是将第二个视图控制器的相同副本推送到堆栈上。当我不得不点击后退按钮六次以回到根视图控制器时,我发现了这一点。

我希望应用程序在唤醒时立即显示手机锁定时的实时视图控制器,而不是根视图控制器。我不知道该怎么做。

2 个答案:

答案 0 :(得分:0)

这可能是因为即使您锁定屏幕,您的应用程序仍然接收位置更新(位置服务可以在真实的后台模式下运行代码),当您按下视图控制器时,堆栈中的前一个仍然存在且仍然接收位置更新和做所有事情都是为了做到这一点,所以即使你推动另一个控制器,如果发生的事情,实现的逻辑必须推动另一个控制器,这个视图控制器可以访问导航控制器,所以只需要添加到堆栈另一个控制器并将其推送(导航控制器对于堆栈中的所有VC仍然相同)

所以你需要做的就是在你推出另一个控制器时停止处理这种情况,并在你弹回控制器时重新启动它

答案 1 :(得分:0)

此错误是由处理程序mapViewDidFailLoadingMap引起的:withError:在控件传递给推送的视图控制器之前被多次调用。我通过对处理程序方法进行三处更改来修复错误: 1)我删除了UIAlertView节目并将其移动到推送的视图控制器; 2)我使用了一个标志(在viewDidAppear :)中初始化,如果第二次调用处理程序,则从处理程序返回而不执行push; 3)在分配推送视图控制器之前,我检查了它是否存在。

完成所有这三项更改后,视图控制器之间的转换正确发生。代码如下:

- (void)mapViewDidFailLoadingMap:(MKMapView *)mapView withError:(NSError *)error

{     [aiView stopAnimating];

if (mapViewFailed > 0) {
    mapViewFailed ++;
    return;
}

if (mapTypeInt == 0) {
    [map setUserTrackingMode:MKUserTrackingModeNone];
    [self removeAsNoticationsObserver];

    if ([currentMode isEqualToString:@"retracingSteps"])
    {
        if (!rvc) {
            rvc = [[RetraceViewController alloc] initWithNibName:@"RetraceViewController" bundle:nil];
        }
        [[self navigationController] pushViewController:rvc animated:YES];
    }
    else{
        if (!ttvc) {
            ttvc = [[TripTableViewController alloc] init];
        }
        [[self navigationController] pushViewController:ttvc animated:YES];
    }
    mapViewFailed ++;


}
else{
    [self setMapType:0];

    NSString *message = [NSString stringWithFormat:@"Your signal is not currently strong enough to download a satellite map. Switching to Standard Map view."];
    UIAlertView *av = [[UIAlertView alloc] initWithTitle:@"Can't Use Satellite Maps"
                                                 message:message
                                                delegate:nil
                                       cancelButtonTitle:@"OK"
                                       otherButtonTitles:nil];
    [av show];
}

}

毫无疑问,有一个更优雅的解决方案,我还不知道,是一个iOS新手。