我正在尝试的应用程序有一个tabbar控制器。
当应用程序启动时,我在AppDelegate中获取用户位置,当我获得准确性时,我需要AppDelegate将NSNotification发送到我应用程序的起始页面(标签栏控制器的索引0)。
收到通知后,此视图会尝试发送包含用户坐标和其他数据的电子邮件,但只要出现MFMailComposeViewController,我就会收到以下错误:
Warning: Attempt to present <MFMailComposeViewController: 0x98a0270> on <UITabBarController: 0x988c630> whose view is not in the window hierarchy!
我错过了什么?
感谢。
编辑:添加一些代码......
这就是我在AppDelegate.m中的内容:
- (void) locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
NSUserDefaults *phoneNumbers = [NSUserDefaults standardUserDefaults];
NSDate *eventDate = newLocation.timestamp;
NSTimeInterval howRecent = [eventDate timeIntervalSinceNow];
if (abs(howRecent) < 10.0) {
[self locationUpdate:newLocation];
smsLoc = newLocation;
if ([[phoneNumbers objectForKey:@"sendSMS"] isEqualToString:@"yes"]) {
[[NSNotificationCenter defaultCenter] postNotificationName:@"sendSMS" object:nil];
} else if ([[phoneNumbers objectForKey:@"sendEmail"] isEqualToString:@"yes"]) {
[[NSNotificationCenter defaultCenter] postNotificationName:@"sendEmail" object:nil];
}
}
}
然后,在我的第一个视图控制器中,我有:
- (void)viewDidLoad
{
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(sendSMS:) name:@"sendSMS" object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(sendEmail:) name:@"sendEmail" object:nil];
}
最后,“sendSMS”的选择器(另一个非常相似):
- (void)sendSMS: (NSNotification *)notification {
NSUserDefaults *phoneNumbers = [NSUserDefaults standardUserDefaults];
if ([phoneNumbers objectForKey:@"first"] || [phoneNumbers objectForKey:@"second"]) {
MFMessageComposeViewController *controller = [[MFMessageComposeViewController alloc] init];
if ([MFMessageComposeViewController canSendText]) {
AppDelegate *deleg = (AppDelegate *)[[UIApplication sharedApplication] delegate];
controller.body = [NSString stringWithFormat:@"some message with coordinates %.4f - %.4f", [deleg currentLocation].coordinate.latitude, [deleg currentLocation].coordinate.longitude];
controller.recipients = [NSArray arrayWithObjects:[phoneNumbers objectForKey:@"first"], [phoneNumbers objectForKey:@"second"], nil];
controller.messageComposeDelegate = self;
[self presentModalViewController:controller animated:YES];
}
}
}
}
第二次编辑:添加更多代码。
UITabBarController *tabBarController = [[UITabBarController alloc] init];
tabBarController.delegate = self;
tabBarController.selectedIndex = 0;
[[tabBarController.tabBar.items objectAtIndex:0] setTitle:NSLocalizedString(@"Home", nil)];
[[tabBarController.tabBar.items objectAtIndex:1] setTitle:NSLocalizedString(@"Requests", nil)];
[[tabBarController.tabBar.items objectAtIndex:2] setTitle:NSLocalizedString(@"Account", nil)];
[[tabBarController.tabBar.items objectAtIndex:3] setTitle:NSLocalizedString(@"Settings", nil)];
//some other controls from DB
[[tabBarController.tabBar.items objectAtIndex:1] setBadgeValue:[NSString stringWithFormat:@"%d",number]];
tabbarController是通过IB制作的,但我在AppDelegate中添加了上面的代码,因为我需要本地化标签栏项目并为其中一个添加徽章。 我在这里做错了吗?
答案 0 :(得分:10)
我不确定你是否解决了这个问题。错误消息表示用于呈现另一个模态viewcontroller的viewcontroller在窗口中不可见。这可能发生在例如:
[VC1 presentModalViewController:VC2];
// Error here, since VC1 is no longer visible on the window
[VC1 presentModalViewController:VC3];
如果您的问题与上述类似,可以修改如下:
if (self.modalViewController != nil) {
[self.modalViewController presentModalViewController:VC3 animated:YES];
} else {
[self.tabBarController presentModalViewController:VC3 animated:YES];
}
如果这不能解决您的问题,也许您可以尝试使用self.tabBarController而不是self来呈现。再一次只是建议,不知道它是否有效。
答案 1 :(得分:2)
使用此功能可能会对某人有所帮助:[[UIApplication sharedApplication].keyWindow.rootViewController presentViewController:picker animated:NO completion:nil];
答案 2 :(得分:1)
由于不推荐使用modalViewController和presentModalViewController,以下内容对我有用:
presentingVC = [[UIApplication sharedApplication] keyWindow].rootViewController;
if (presentingVC.presentedViewController) {
[presentingVC.presentedViewController presentViewController:VC3 animated:YES completion:nil];
} else {
[presentingVC presentViewController:VC3 animated:YES completion:nil];
}
答案 3 :(得分:0)
您可以遵循此模式
[VC1 presentModalViewController:VC2];
//
[**VC2** presentModalViewController:VC3];