I have an educational app working fine with tab bars. One of the tabs is a test for the user. If a user taking the test selects another tab, I would like an action sheet to display to confirm they really want to exit the test since their test results will be lost.
I can’t get the action sheet to display. I am getting syntax errors with the first three examples below. The 4th example will compile OK but the app aborts. I can’t figure out what should go after the self. Or possibly one of the other examples would work if I had the syntax correct.
- (void)tabBarController:(UITabBarController *)tabBarController
didSelectViewController:(UIViewController *)viewController {
NSLog(@"Tab Bar Controller reached");
UIActionSheet *actionSheet = [[UIActionSheet alloc]
initWithTitle:@"This will end the test.
Are you sure you want to leave?"
delegate:self
cancelButtonTitle:@"Cancel"
destructiveButtonTitle:@"Yes,
cancel the test."
otherButtonTitles:nil];
[actionSheet showInView:self.view];
[actionSheet showInView:elements1AppDelegate.window];
[actionSheet showFromTabBar:self.tabBarController.tabBar];
[actionSheet showFromTabBar:self];
Ultimately, once I get the action sheet to display, I will either proceed to the tab selected or stay in the test view depending on whether the user decides to exit or not. Any help/suggestions would be appreciated. Thanks.
The name of the method
tabBarController:didSelectViewController:should indicate that it’s too late to stop the selection. Its return typevoidindicates there is not much you can do about it. Instead focus on method names that have “will” or “should” in them, and return types likeBOOLs such astabBarController:shouldSelectViewController:. So here is some basic code that does what you want.I don’t know the actual classname of your test’s view controller so I’ll use
QuizControlleras a classname.QuizControlleris aUIViewControllersubclass.QuizController.m
EDIT (In response to comment quoted)
No. I am suggesting that you take this code and integrate the design pattern into your
UIViewControllersubclass that handles your test. Although this is a working example (providing you supply UI to toggle the_testInProgressivar.)Yup.
Huh? Your
UITabBarControlleris almost certainly yourrootViewController. But unless you have done something very odd likeAppDelegate : UITabBarController <UIApplicationDelegate>, by the way don’t do that, then it is extremely unlikely that your “appdelegate” and yourUITabBarControllerare the same. Much more likely yourAppDelegateis yourtabBarController‘s delegate.If just setting the
tabBarController.delegateproperty on appearance is bad (and it could very well be), i.e. some other object needs to be thetabBarController‘s delegate, then you’ll have to forward a message to that view controller to see if a test is in progress. For this you could actually leave almost all of the code in the example unchanged. Of course you would have to remove theself.tabBarController.delegate = self;inviewDidAppear:. And put the following in yourAppDelegate(presuming that’s thetabBarController‘s delegate):This implementation essentially forwards the responsibility to answer the question to the view controller, provided it will answer the question.
In my opinion the “take test” view controller should simply become selected when the user taps the tab for it. And its view should contain a button with something to the effect of ‘start test’ on it. But that’s just my opinion.
But whatever the case is the application’s knowledge of whether the user is taking a test should reside in the view controller that administers the test.