My app has four tabs 3 of them moves to a separate view controller . The fourth one enable the user to log out from the app what i need here is to add an alert message when the fourth tab is pressed can any one help me how to do so ?
I did search for solutions and found nothing .
Thanks in advance
first make sure your appdelegate.h file contains the UITabBarControllerDelegate to be able to access UITabBar methods .. so the definition of your AppDelegate.h should look like this
#interface AppDelegate : UIResponder <UIApplicationDelegate,UITabBarControllerDelegate >
then go to AppDelegeate.m and define a global boolean variable
bool shouldSelectViewController;
this variable decides whether or not your log in screen should be viewed or not .. although we are not going to manipulate this variable in the code but for some reason my code does not work as you wish without adding this variable it does not make any sense but xcode surprises me!
now add this method
- (BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController {
if([viewController.title isEqualToString:#"your log in view controller title"]) {
//TODO show alert here
return shouldSelectViewController;
}
return YES;
}
}
then add a method to transform the user to the log in page if he confirms the alert
-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
if(buttonIndex == 1) //here I assume that the alert has two buttons 0:cancel 1:Ok
{
// because you are in the AppDelegate you can't access the UITabBarController directly so you get it by writing this line of code
UITabBarController * tabBarController = (UITabBarController *)_window.rootViewController;
NSInteger destinationTabIdx = 3; //this is the index of the tab we want ot transfer the user to
UIView * fromView = tabBarController.selectedViewController.view; //move the user from current view he is in
UIView * toView = [[tabBarController.viewControllers objectAtIndex:destinationTabIdx] view]; // to this view which is view at tab index 3
//now do the transition to the view you want with optional animation
[UIView transitionFromView:fromView toView:toView duration:0.8
options:(destinationTabIdx > tabBarController.selectedIndex ? UIViewAnimationOptionTransitionFlipFromLeft: UIViewAnimationOptionTransitionFlipFromRight)
completion:^(BOOL finished) {
if (finished) {
tabBarController.selectedIndex = destinationTabIdx;
}
}];
}
}
Inside the forth viewController ViewWillappear method show the alertview.When ever it is shown the alert pops out
Use UITabBarControllerDelegate method:
- (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController {
if (tabBarController.selectedIndex == 3) {
//show alert here
}
-(void)viewWillAppear:(BOOL)animated
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Alert" message:#"
msg" delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
[alert show];
}
//Delegate
- (void)alertView:(UIAlertView *)alertView willDismissWithButtonIndex: (NSInteger)buttonIndex
{
if(buttonIndex==0)
{
self.tabBarController.selectedIndex = 1;
//Move User to the FirstTabBarViewController
}
}
In Your ForthViewController method ViewWillappear use UIAlertView
It may be helpful
When you click the tabbar this method will be called so handle your logic in this method
- (void)tabBarController:(UITabBarController *)rootController didSelectViewController:(UIViewController *)viewController {
}
So if you want to show to the user an alert view when he/she taps on a tab bar item and you don't want to change to the corresponding view controller of the UITabBarItem then you should try this:
- (BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController {
if([viewController isKindOfClass:[TheViewControllerOfYourAlertTab class]) {
//TODO show alert here
return NO;
}
return YES;
}
Also, if you want to show the ViewController of the UITabBar which will show the alert view after the user selects a button from the alert view, you will need an extra BOOL value to be added in the if statement something like:
- (BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController {
if([viewController isKindOfClass:[TheViewControllerOfYourAlertTab class] && shouldShowAlert) {
//TODO show alert here
return NO;
}
return YES;
}
And the shouldShowAlert by default will be YES, when the user selects the required button from the alert view you can do:
shouldShowAlert = NO;
self.selectedIndex = indexOfYourAlertTabBarItem;
Also make sure to set the delegate of your alertView.
Related
I have already created UI alert and call a function.
UIAlertView *alertView1 = [[UIAlertView
alloc]initWithTitle:#"Test"message:#"Working 1!!"delegate: self
cancelButtonTitle:#"OK"otherButtonTitles:nil];
[alertView1 show];
Method for call newView viewController
- (void)alertView:(UIAlertView *)alertView
didDismissWithButtonIndex:(NSInteger) buttonIndex
{
if (buttonIndex == 0)
{
NSLog(#"Cancel Tapped.");
}
else if (buttonIndex == 1)
{
// NSLog(#"OK Tapped. Hello World!");
UIViewController *newView = [[UIViewController alloc] init];
[self presentViewController:newView animated:YES completion:nil];
}
}
I have created a new class named "newView" and also add "UIAlertViewDelegate" in present view controller.
But my problem is, I couldn't connect the newView viewcontroller with my present view controller.
Here you are creating object in memory so that's why you can now only access properties and public methods of newView. Can not make presentation of newView.
You can achieve this by 2 ways.
Either you can make this possible by calling Segue or you have to create newView object from Storyboard.
ViewController *entryController = [self.storyboard instantiateViewControllerWithIdentifier:#"go"];
[self.navigationController pushViewController:entryController animated:YES];
my application story board is as following
it is a tab bar controller based application with one of the tabs embedded in a navigation controller. when the user click on the first tab (view1) and click a button inside this view, he will be moved to view2. instead of using the back button to return to view1, I want the user to click on the tab item in order to return to view1 which works fine. However, I want to view an alert when the user clicks on the tab and he is in View2. I am using shouldSelectViewController and didSelectViewController delegate methods to check what tab is clicked and view the alert. The problem is that I can't reach View2 from these methods in the delegate to inform the application to view the alert only when user is in view2 and clicks the tab.
I tried to use this code inside shouldSelectViewController
if (tabBarController.selectedIndex == 0) {
NSLog(#"Delegate nav title: %#", tabBarController.selectedViewController.navigationItem.title);
}
these lines always return the title of view1
As they are in the same navigation controller, they have the same navigation item. Each view can configure this navigation item but it is generally the same object. That is why it returns the same title. Try setting up the navigation item title in second view controller's viewDidLoad method.
I finally found a solutino to my problem
first I added a static variable to View2 and called it inView2 as following
in View2.h
#interface
{}
+ ( BOOL ) isInQuizViewController;
+ ( void )setInQuizViewController:(BOOL)inQuizVal;
//...
#end
in View2.m
#implementation
static BOOL inView2 = NO;
+(BOOL)isInView2
{
return inView2;
}
+ ( void )setInView2:(BOOL)Val
{
inView2 = val;
}
these two methods are for setting and getting the value of inView2 which tells me whether or not the user is currently in View2
in View1.h create an IBAction associated with the button that will transmit from View1 to View2 and connect it to your storyboard
- (IBAction)GoToView2:(id)sender;
go to View1.m and import
#import "View2.h"
and implement your IBAction method to set the InView2 to YES
- (IBAction)GoToView2:(id)sender {
[View2 setInView2:YES];
}
then in the delegate.m
#import "View2.h"
#implementation AppDelegate
UITabBarController * _tabBarController;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
_tabBarController = (UITabBarController *)_window.rootViewController;
_tabBarController.delegate = self;
// Override point for customization after application launch.
return YES;
}
I defined a global _tabBarController and set it to _window.rootViewController and set its delegate to this delegate and remember to import "View2.h"
going to the ShouldSelectViewController method (note that this method is called before the transition to the selected tab ViewController, hence it is perfect for decision making of whether or not the selected tab viewController should be displayed to the user).
so in ShouldSelectViewController method I did the following
- (BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController {
if(tabBarController.selectedIndex == 2)
{
if ([View2 isInView2]) {
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"alert"
message:#"are you sure you want to exit?"
delegate:self
cancelButtonTitle:#"Cancel"
otherButtonTitles:#"Yes",nil];
[alertView show];
return NO;
}
}
return YES;
}
-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
if(buttonIndex == 1)
{//ok button pressed
// NSInteger destinationTabIdx = 2;
// UIView * fromView = tabBarController.selectedViewController.view;
// UIView * toView = [[[[[tabBarController.viewControllers objectAtIndex:destinationTabIdx] navigationController] viewControllers] objectAtIndex:0] view];
UINavigationController *nav = (UINavigationController *)_tabBarController.selectedViewController;
NSLog(#"vc title: %#",nav.title);
// [UIView transitionFromView:fromView toView:toView duration:0.8
// options: UIViewAnimationOptionTransitionNone
// completion:^(BOOL finished) {
// if (finished) {
// tabBarController.selectedIndex = destinationTabIdx;
// }
// }];
[nav popViewControllerAnimated:YES];
[QuizViewController setInQuizViewController:NO];
NSLog(#"app delegate transistion done");
}
}
I have a segue that I want to be preformed when I push the Manual Entry and Scan Tag buttons on my AlertView.
#implementation triageViewController
- (IBAction)addNew:(id)sender {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Add A New Entry"
message:#"Choose a way to add a new entry."
delegate:nil
cancelButtonTitle:#"Cancel"
otherButtonTitles:#"Manual Entry", #"Scan Tag", nil];
[alert show];
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
if (buttonIndex != alertView.firstOtherButtonIndex) {
[self performSegueWithIdentifier:#"manual" sender: self];
}
if (buttonIndex != alertView.cancelButtonIndex) {
[self performSegueWithIdentifier:#"scan" sender: self];
}
}
(I realize this would probably make the cancel button preform a segue right now, but i'm more concerned with making it work)
I have the two segues in my storyboard, going from a UITabViewController to two different UIViewControllers. neither of these are being called, so when I tap them. I tried using both push and modal segues, but neither one was working.
I also tried the if/else statement like so:
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
if (buttonIndex == 0) {
[self performSegueWithIdentifier:#"manual" sender: self];
}
if (buttonIndex == 1) {
[self performSegueWithIdentifier:#"scan" sender: self];
}
}
But this is not working either.
Could someone help me figure out what is going wrong? Again in case I was unclear, I want to preform a segue from a UIAlertView pop-up located on a UITabBarController to two separate UIViewControllers.
Thanks
It looks like your UIAlertView has a delegate of nil so your function is never being called. Set that to self and then in your view controller's header make sure you're implementing the UIAlertViewDelegate protocol.
I have 3 TabBarItems in UITabBarController:
<UINavigationController: 0xc76a680>
<SplitViewController: 0xc76a170>
<UINavigationController: 0xca5e6f0>
And I have the method in AppDelegate:
- (BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController
{
NSLog(#"tab selected index %#",viewController);
if (viewController == nil ) // I NEED TO IMPLEMENT A CHECk HERE
{
//show popup
return NO; //does not change the tab
}
return YES; //does change the tab
}
So how to check that view controller which should be selected is the second Navigation Controller? Thx
try this code
- (BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController
{
BOOL result;
if (viewController == [self.tabBarController.viewControllers objectAtIndex:2]) //assuming the index of uinavigationcontroller is 2
{
NSLog(#"Write your code based on condition");
result = NO;
}
else {
result = YES;
}
return result;
}
You could check for viewcontroller.title property and then make the decision. Assuming that title for both viewcontrollers are different.
I have an two controllers 1st is self and 2nd is maincontroller, where I'm pushing maincontroller in stack, so the back button is automatically coming.
Here I need to make an alert when the user presses the back button.
How can I do this?
Or you can use the UINavigationController's delegate methods. The method willShowViewController is called when the back button of your VC is pressed.
- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated;
First hide the back button by using
self.navigationItem.hidesBackButton = YES;
and then create your own Custom Button:
UIBarButtonItem *backBtn =[[UIBarButtonItem alloc]initWithTitle:#"back" style:UIBarButtonItemStyleDone target:self action:#selector(popAlertAction:)];
self.navigationItem.leftBarButtonItem=backBtn;
[backBtn release];
and your selector is here:
- (void)popAlertAction:(UIBarButtonItem*)sender
{
//Do ur stuff for pop up
}
Best and Easiest way
Try putting this into the view controller where you want to detect the press:
-(void) viewWillDisappear:(BOOL)animated {
if ([self.navigationController.viewControllers indexOfObject:self]==NSNotFound) {
// back button was pressed. We know this is true because self is no longer
// in the navigation stack.
}
[super viewWillDisappear:animated];
}
Create your own UIBarButtonItem and set it as the leftBarButtonItem in viewDidLoad method of mainController.
For example (here I used a system item but you can also create a different one, see class reference for details).
UIBarButtonItem *leftBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:#selector(showAlertView:)];
self.navigationItem.leftBarButtonItem = leftBarButtonItem;
// only if you don't use ARC
// [leftBarButtonItem release];
where
- (void)showAlertView:(id)sender
{
// alert view here...
}
add a custom back button with an action and set your alert in that action method.You can add your custom back button from here: http://www.applausible.com/blog/?p=401
viewControllerCount - is the var that holds the number of viewControllers previously was in the UINavigationController. Then, we check if viewControllerCount > [viewControllers count] if so, we know that we will get back (i.e. Back button imitation).
- (void)navigationController:(UINavigationController *)navigationController
willShowViewController:(UIViewController *)viewController
animated:(BOOL)animated
{
NSArray *viewControllers = [navigationController viewControllers];
if (viewControllerCount > [viewControllers count])
{
// your code
}
viewControllerCount = [viewControllers count];
}
extension ViewController: UINavigationControllerDelegate {
// when the self != viewcontroller ,it's mean back
func navigationController(_ navigationController: UINavigationController, willShow viewController: UIViewController, animated: Bool) {
if self != viewController {
// your code
}
}}
create a button and give the button action as follows.
[self alert];
and when the alert is displayed, after tapping over yes
[self.navigationController popViewController];
after this,
self.navigationController.LeftBarButton = myButton;
this may help