Pour compléter Eric réponse (qui a laissé de côté popovers, les contrôleurs de la navigation, tabbarcontrollers, vue contrôleurs ajouté que les sous-vues de certains autres contrôleurs de vue en traversant), voici ma version de retour actuellement visible-vue-contrôleur:
=====================================================================
// Dans AppDelegate.h
//Whenever you are creating any popover plz assign it to this variable.
@property (nonatomic, weak) UIPopoverController *currVisiblePopOver;
=====================================================================
// Dans AppDelegate.m
- (UIViewController*)topMostViewController {
// Handling UIPopoverController
if (self.currVisiblePopOver && [self.currVisiblePopOver isKindOfClass:[UIPopoverController class]] && [self.currVisiblePopOver isPopoverVisible])
{
return self.currVisiblePopOver.contentViewController;
}
else
{
return [self topViewControllerWithRootViewController:[UIApplication sharedApplication].keyWindow.rootViewController];
}
}
- (UIViewController*)topViewControllerWithRootViewController:(UIViewController*)rootViewController {
// Handling UITabBarController
if ([rootViewController isKindOfClass:[UITabBarController class]]) {
UITabBarController* tabBarController = (UITabBarController*)rootViewController;
return [self topViewControllerWithRootViewController:tabBarController.selectedViewController];
}
// Handling UINavigationController
else if ([rootViewController isKindOfClass:[UINavigationController class]]) {
UINavigationController* navigationController = (UINavigationController*)rootViewController;
return [self topViewControllerWithRootViewController:navigationController.visibleViewController];
}
// Handling Modal views
else if (rootViewController.presentedViewController) {
UIViewController* presentedViewController = rootViewController.presentedViewController;
return [self topViewControllerWithRootViewController:presentedViewController];
}
// Handling UIViewController's added as subviews to some other views.
else {
for (UIView *view in [rootViewController.view subviews])
{
id subViewController = [view nextResponder]; // Key property which most of us are unaware of / rarely use.
if ( subViewController && [subViewController isKindOfClass:[UIViewController class]])
{
return [self topViewControllerWithRootViewController:subViewController];
}
}
return rootViewController;
}
}
=====================================================================
// En tout point de vue où nous sommes rejetant la liste
#pragma mark - UIPopoverControllerDelegate methods
- (void)popoverControllerDidDismissPopover:(UIPopoverController *)popoverController
{
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
appDelegate.currVisiblePopOver = nil;
popoverController = nil;
}
// En tout point de vue où nous sommes montrant liste nous avons besoin d'avoir les 2 lignes où "popOverController' est le nom de l'instance de la UIPopoverController
popOverController.delegate = self;
[(AppDelegate *)[[UIApplication sharedApplication] delegate] setCurrVisiblePopOver:popOverController];
//---------- (exemple ci-dessous) ---------- //
- (IBAction)syncWarningsBtnAction:(id)sender
{
SyncWarningsViewController *syncWarningsViewController = [[SyncWarningsViewController alloc] init];
popOverController = [[UIPopoverController alloc] initWithContentViewController:syncWarningsViewController];
popOverController.delegate = self;
[(AppDelegate *)[[UIApplication sharedApplication] delegate] setCurrVisiblePopOver:popOverController];
[popOverController presentPopoverFromRect:self.btnSync.frame inView:self.view permittedArrowDirections:UIPopoverArrowDirectionDown animated:YES];
}
=====================================================================
Et maintenant, tout ce que vous devez faire pour obtenir la meilleure plus-vue-contrôleur est d'appeler la méthode ci-dessus comme suit:
UIViewController *topMostViewControllerObj = [self topMostViewController];