navigationItem added to ABPersonViewController disappears when app resumed - ios

I created an ABPersonViewController and added a done button:
ABRecordRef rec = ABAddressBookGetPersonWithRecordID(addrBook, recordID);
if (rec) {
ABPersonViewController* personController = [[[ABPersonViewController alloc] init] autorelease];
personController.displayedPerson = rec;
personController.personViewDelegate = self;
personController.allowsEditing = NO;
UIBarButtonItem* doneButton = [[[UIBarButtonItem alloc]
initWithBarButtonSystemItem:UIBarButtonSystemItemDone
target: self
action: #selector(dismissModalView:)] autorelease];
UINavigationController *navController = [[[UINavigationController alloc] initWithRootViewController:personController] autorelease];
[self.appViewController presentModalViewController:navController animated: YES];
// this needs to be AFTER presentModal, if not it does not show up (iOS 4 regression: workaround)
personController.navigationItem.rightBarButtonItem = doneButton;
I should have been suspicious that it had to be added AFTER the view was presented.
This worked until the app was sent to the background with this view active. When the app was restored the done button was no longer there. I've tried many ways to add this Done button but could never get it to remain through an app pause.

Here is the solution. Create an empty UIViewController in front of the ABPersonViewController. This will cause the ABPersonViewController to have a back button rather than the created done button. Override ABPersonViewController (DisplayContactViewController below) so you can implement viewDidDisappear. This will be called when the user presses the back button. In viewDidDisappear you can take down the entire navigation stack (including the empty View controller) and get back to your original view.
DisplayContactViewController* personController = [[[DisplayContactViewController alloc] init] autorelease]; //
personController.displayedPerson = rec; // the ABPersonRecord to display
personController.personViewDelegate = self;
personController.allowsEditing = NO;
personController.contactsPlugin = self; //this is my hook so I can dismiss the picker view later
// create this so DisplayContactViewController will have a "back" button.
UIViewController* parentController = [[[UIViewController alloc] init] autorelease];
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:parentController];
[navController pushViewController:personController animated:YES];
[self.appViewController presentModalViewController:navController animated: YES];
Here is DisplayContactViewController viewDidDisappear.
[super viewDidDisappear: animated];
[self.contactsPlugin.appViewController dismissModalViewControllerAnimated:NO];

Related

iOS - [ObjC] NavigationBarButtonItem is not showing when the navigation bar's root view is presented modally

In my app I have two tabs that handle different set of functions.
One tab is the user tab, when the user switch to this tab, the tab controller checks whether the user has logged in. If not, it shows a button(LoginBtn) which triggers a log in view controller to show when tapped.
I intend to present the log in controller modally with a navigation bar.
However, the navigation bar is not showing the right button item although I've initiated it.
Here's the code
- (void)clickLoginBtn{
LogginController* _cLogginController = [[LogginController alloc] init];
UINavigationController *_cNavController = [[UINavigationController alloc] initWithRootViewController:_cLogginController];
_cNavController.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:#"取消" style:UIBarButtonItemStylePlain target:self action:#selector(dismissLoginView)];
[_cNavController.navigationItem.rightBarButtonItem setTintColor:kColorWhite];
_cNavController.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
[self presentViewController:_cNavController animated:YES completion:nil];
}
What could be the problem? Is it possible that is because I present to controller modally?
You have put your buttons to the login controller:
_cLogginController.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:#"取消" style:UIBarButtonItemStylePlain target:self action:#selector(dismissLoginView)];
You shouldn't add navigation items to the navigation controller.
try this code.I think this issue is solved by this code
- (void)clickLoginBtn{
LogginController* _cLogginController = [[LogginController alloc] init];
_cLogginController .hidesBottomBarWhenPushed=No;//You need to add this line
UINavigationController *_cNavController = [[UINavigationController alloc] initWithRootViewController:_cLogginController];
_cNavController.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:#"取消" style:UIBarButtonItemStylePlain target:self action:#selector(dismissLoginView)];
[_cNavController.navigationItem.rightBarButtonItem setTintColor:kColorWhite];
_cNavController.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
[self presentViewController:_cNavController animated:YES completion:nil];
}
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
DemoViewController * _cLogginController = [[DemoViewController alloc]init];
_cLogginController = [storyboard instantiateViewControllerWithIdentifier:#"DemoViewController"];
_cLogginController .hidesBottomBarWhenPushed = NO;
UINavigationController *_cNavController = [[UINavigationController alloc]initWithRootViewController:_cLogginController];
_cNavController.navigationItem.rightBarButtonItem.tintColor = [UIColor blueColor];
_cNavController.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
_cLogginController.navigationItem.title = #"取消";
UIBarButtonItem *flipButton = [[UIBarButtonItem alloc]
initWithTitle:#"Flip"
style:UIBarButtonItemStyleBordered
target:self
action:#selector(flipView:)];
flipButton.tintColor = [UIColor grayColor];
_cLogginController.navigationItem.rightBarButtonItem = flipButton;
[self presentViewController:_cNavController animated:YES completion:nil];

Present a View Controller modally when selected in Tab Bar Controller

I have this pretty standard Tab Bar Controller setup:
UIViewController *homeViewController = [[PLOTHomeViewController alloc] init];
UIViewController *upcomingViewController = [[PLOTUpcomingViewController alloc] init];
UIViewController *checkInViewController = [[PLOTCheckInViewController alloc] init];
UIViewController *watchlistViewController = [[PLOTWatchlistViewController alloc] init];
UIViewController *profileViewController = [[PLOTProfileViewController alloc] init];
PLOTNavigationController *homeNavVC = [[PLOTNavigationController alloc] initWithRootViewController:homeViewController];
PLOTNavigationController *upcomingNavVC = [[PLOTNavigationController alloc] initWithRootViewController:upcomingViewController];
PLOTNavigationController *checkInNavVC = [[PLOTNavigationController alloc] initWithRootViewController:checkInViewController];
PLOTNavigationController *watchlistNavVC = [[PLOTNavigationController alloc] initWithRootViewController:watchlistViewController];
PLOTNavigationController *profileNavVC = [[PLOTNavigationController alloc] initWithRootViewController:profileViewController];
self.tabBarController = [[PLOTTabBarController alloc] init];
self.tabBarController.viewControllers = [NSArray arrayWithObjects:homeNavVC, upcomingNavVC, checkInNavVC, watchlistNavVC, profileNavVC, nil];
However, I'm trying to work out how, when the user selects the middle tab (checkInViewController), I can present that View Controller modally (fullscreen)? I'd maybe imagine something in the viewDidAppear method in that VC, but I'm not sure if you can present yourself modally, if you're a VC? What's the best approach for this?
You can use
[self presentViewController:checkInViewController animated:YES completion:nil];
Then hide the tab and navigation bars in the destination view controller's viewWillAppear:
-(void)viewWillAppear:(BOOL)animated {
[self.navigationController setNavigationBarHidden:YES animated:YES];
[self.tabBarController.tabBar setHidden:YES];
}

Add a navigationbar with a back button to the app [duplicate]

This question already has answers here:
how to create back button in navigation bar
(3 answers)
Closed 9 years ago.
I need a step by step tutorial to add a navigation bar including a back button to my project.
My rootViewController defined in the AppDelegate is the LoginViewController. After successfull login it goes to the MainView and then to the SingleView
How would I add a navigation bar and a back button? This is the last thing I need for my app. I already tried many things
for example:
everything in the viewDidLoad method
First Try
UIBarButtonItem *anotherButton = [[UIBarButtonItem alloc] initWithTitle:#"Show" style:UIBarButtonItemStylePlain target:self action:#selector(refreshPropertyList:)];
self.navigationItem.rightBarButtonItem = anotherButton;
Second Try
UIBarButtonItem *anotherButton = [[UIBarButtonItem alloc] initWithTitle:#"Show" style:UIBarButtonItemStylePlain target:self action:#selector(refreshPropertyList:)];
self.navigationItem.rightBarButtonItem = anotherButton;
What exactly do I write into the RootViewController and what do I write into the other UIViewController to get a butotn?
Edit 2 after Popeye's suggestion
//Appdelegate.m
LoginViewController *viewController = [[LoginViewController alloc] init];
UINavigationController *navCon = [[UINavigationController alloc] initWithRootViewController:viewController];
[navCon setNavigationBarHidden:NO];
self.window.rootViewController = viewController;
//LoginViewController.m
[self.navigationController setNavigationBarHidden:NO];
ToDoListViewController *viewController = [[ToDoListViewController alloc] init];
viewController.stringUserId = //userid//;
[self presentViewController:viewController animated:NO completion:nil];
//ToDoListViewController.m
[self.navigationController setNavigationBarHidden:NO];
UIBarButtonItem *myBarButtonItem = [[UIBarButtonItem alloc] init];
myBarButtonItem.title = #"Back";
UINavigationItem *right = [[UINavigationItem alloc] initWithTitle:#"Hello!"];
right.leftBarButtonItem = myBarButtonItem;
[self.navigationController.navigationBar pushNavigationItem:right animated:YES];
still, no buttons!
Best way is add NavigationController to your rootViewController and you also able to hide and show NavigationBar by using following code
yourNavigationController.navigationBarHidden:YES/NO;
you can add rootViewController with navigationController by
LoginViewController *loginVC = [[LoginViewController alloc] init];
UINavigationController *navCon = [[UINavigationController alloc] initWithRootViewController:loginVC];
navCon.navigationBarHidden = YES/NO;
self.window.rootViewController = navCon;
.
.
.

how to add tab bar controller from the second view controller [duplicate]

This question already has an answer here:
Showing login view controller before main tab bar controller
(1 answer)
Closed 9 years ago.
Im beginner to IOS app development learning.
I have a login screen as my first view controller and i need the second view controller to be a tab bar view controller .with 4 different tabs and i have 4 different XIB's for them.
some one help me to go ahead.
Best way you can do is Present the login screen modally when the app starts from your tab bar controller first screen, add code for presenting login screen in viewWillAppear and after login dismiss the screen. You can create TabBarController in appDelegate like this
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
UITabBarController tabBarController=[[UITabBarController alloc] init];
FirstViewController *firstVC = [[UIViewController alloc] initWithNibName:#"FirstVC" bundle:nil];
UINavigationController *firstNavController = [[UINavigationController alloc] initWithRootViewController: firstVC];
SecondViewController *secondVC = [[UIViewController alloc] initWithNibName:#"secondVC" bundle:nil];
UINavigationController *secondNavController = [[UINavigationController alloc] initWithRootViewController:secondVC];
tabBarController.viewControllers = [NSArray arrayWithObjects: firstNavController, secondNavController, nil];
tabBarController.selectedIndex=0;
tabBarController.delegate = self;
UITabBarItem *item1 = [[UITabBarItem alloc] initWithTitle:#"Movies" image:[UIImage imageNamed:#"MoviesTAB.png"] tag:1];
[firstVC setTabBarItem:item1];
UITabBarItem *item2 = [[UITabBarItem alloc] initWithTitle:#"Music" image:[UIImage imageNamed:#"musicTAB.png"] tag:2];
[seconfVC setTabBarItem:item2];
tabController.tabBar.translucent = NO;
tabController.tabBar.barStyle = UIBarStyleBlack;
tabBarController.tintColor = [UIColor whiteColor];
self.window.rootViewController = tabController;
return YES;
}
Best way is use storyboard and there just have one initial UIViewController and from that make segue to UITabBarViewController.
http://youtu.be/a_DCTSTv1Mw
If you want to make it through xib make a UITabBarViewController and add viewControllers to the array of object of that UITabBarViewController's object.
Sample code :
NSMutableArray *arrViewControllers = [[NSMutableArray alloc] init];
UIViewController *tabController;
UIImage *tabImage ;
NSString *tabTitle;
for (int i= 0; i < 3; i++) {
switch (i) {
case 0:
tabController = [[ViewController alloc] init];
tabImage = [UIImage imageNamed:#"icon1.png"];
tabTitle = #"Text";
break;
case 1:
tabController = [[ImageDemoViewController alloc] init];
tabImage = [UIImage imageNamed:#"icon2.png"];
tabTitle = #"Image";
break;
case 2:
tabController = [[TableDemoViewController alloc] init];
tabImage = [UIImage imageNamed:#"icon3.png"];
tabTitle = #"Table";
break;
}
// set the image and title using some properties of UIViewController
tabController.tabBarItem.image = tabImage;
tabController.tabBarItem.title = tabTitle;
//add objects to array
[arrViewControllers addObject:tabController];
[tabController release];
}
_baseController = [[UITabBarController alloc] init];
_baseController.viewControllers = arrViewControllers;
[arrViewControllers release];
go to your appDelegate
1.create a viewController for login screen.
LoginViewController *viewController1 = [[LoginViewController alloc] initWithNibName:#"LoginViewController" bundle:nil];
2.create a navigationController with root view your login ViewController.
UINavigationController *nVC = [[UINavigationController alloc] initWithRootViewController:viewController1];
3.make navigationController to root view of window.
self.window.rootViewController = self.nVC;
[self.window makeKeyAndVisible];
Now go to Touch-Up-Inside method of login button in LoginViewController.
1.After validation of password and userId initialise your viewControllers for tabbar and TabbarViewController.
UiViewController ...*yourViewControllers,..,
UITabBarController *YourtabBarController = [[UITabBarController alloc] init];
2.Now add these viewControllers to your tabbarController.
YourtabBarController.viewControllers = #[ YourViewController1,YourViewController2,YourViewController3,......];
3.Finally push this tabbarController to navigationControllere.
[self.navigationController pushViewController:YourtabBarController animated:NO];

No back button on UINavigationBar inside UITabbarController

I am working on an app for iOS6 and iOS7. I just found a weird behavior that varies between the two versions.
My app has a UITabbarController with 3 tabs and each tab as UINavigationController in it.
On iOS6 when I do a push on any of these navControllers the 2nd ViewController after the root does not show a back button in the navigationBar. However any subsequent pushes show the back button.
On iOS7, however, I see a back button with no title after 1st push and a back button with title "Back" after subsequent push.
Is this behavior normal? I can't understand why this is happening. How do I make sure I have a back button after every push irrespective of the OS version.
EDIT
Here is some code for clarity :
This is how I am initiating the UITabBarController
- (id)init {
self = [super init];
if (self) {
NSMutableArray *vcs = #[].mutableCopy;
JBNavigationVC *navVC = nil;
if ([JBUser sharedInstance].isLoggedIn) {
_productCategoryVC = [[JBProductCategoryVC alloc] init];
_productCategoryVC.title = #"Products";
navVC = [[JBNavigationVC alloc] initWithRootViewController:_productCategoryVC];
[vcs addObject:navVC];
_triviaVC = [[JBTriviaVC alloc] init];
_triviaVC.title = #"Trivia";
navVC = [[JBNavigationVC alloc] initWithRootViewController:_triviaVC];
[vcs addObject:navVC];
_infoVC = [[JBInfoVC alloc] init];
_infoVC.title = #"Info";
navVC = [[JBNavigationVC alloc] initWithRootViewController:_infoVC];
[vcs addObject:navVC];
}
self.viewControllers = vcs;
}
return self;
}
JBNavigationVC is a subclass of UINavigationController. This is how I transition to the tabbarVC in AppDelegate
_tabBarVC = [[JBTabBarVC alloc] init];
[_tabBarVC setSelectedIndex:0];
[self.window setRootViewController:_tabBarVC];
This sets the first VC to front. This VC is has a UITableView in it and in - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath I do this:
if (!_productsListVC) {
_productsListVC = [[JBProductsListVC alloc] init];
}
_productsListVC.category = category;
[self.navigationController pushViewController:_productsListVC animated:YES];

Resources