Newbie question for iOS -- I'm really confused with how navigation view works in a tabview.
Right now I have a tabview that has 2 views. In the second tab I have a button. When the button is clicked I'd like a new window to show up with some information, and the new window needs a Back button on top that goes back to the second tab.
I followed some tutorials and put a NavigationController in secondTab.xib, added the line
#property (nonatomic, retain) IBOutlet UINavigationController *navController;
to secondTab.h, and
NewWindowController *newWindow = [[NewWindowController alloc] initWithNibName:#"NewWindowController" bundle: nil];
[self.navController pushViewController:newWindow animated:YES];
NSLog(#"clicked");
to my button implementation for -(IBAction) click: (id)sender
When I clicked the button in my second tab, the log shows "clicked" but my view is not changing.
Is there some setting I need to change for File's Owner/Navigation Controller outlets/referencing outlets etc...?
Thanks!
You don't want a property for the UINavigationController, you want to push onto the current navigation controller like so:
NewWindowController *newWindow = [[NewWindowController alloc] initWithNibName:#"NewWindowController" bundle: nil];
[self.navigationController pushViewController:newWindow animated:YES];
NSLog(#"clicked");
When a UIViewController is associated with a UINavigationController (i.e. it's part of a navigation controller hierarchy) then its navigationController property will be set, so you can access it like I've shown.
Related
In my viewController2 I have different UIView's, and let's say that when I load my viewController2 from viewController3 I need to show only UIView2. Is it possible to do that?
viewController2, has many forms. For example, after clicking the button on form1 it would hide form1 and show form2 and so on. Now, the problem is if I load my viewController2 from viewController3 is it possible to just show form2 and not form1?
Here's how I load my viewController2:
[APP_DELEGATE setUIBlockingEnabled:[NSNumber numberWithBool:NO]];
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
appDelegate.rootViewController = nil;
appDelegate.rootViewController = [[RootViewController alloc] init];
appDelegate.window.rootViewController = appDelegate.rootViewController;
appDelegate.window.backgroundColor = [UIColor clearColor];
RegistrationViewController *controller = [[RegistrationViewController alloc]init];
[appDelegate.rootViewController moveToViewController:controller];
//viewController2
#property (nonatomic, strong) UIView *rectHolder1;
#property (nonatomic, strong) UIView *rectHolder2;
rectHolder1 and rectHolder2 has different subviews, and upon page load I am showing rectHolder1 and rectHolder2 is not visible. When the user clicks on the rectHolder1's button it would hide rectHolder1 and show rectHolder2. Now how can I directly show rectHolder2 if I am loading viewController2 from another viewController
You should have to manage this kind of stuff in viewWillAppear of your viewController2. Set some flag when you come from VC3 to VC2 so that you can differentiate that you are coming from VC3 or not! If your flag is true(I mean you are coming from VC3) then show your desired view else show other content that you want to show! If you are going forward means you have pushing VC2 from VC3(which less possible as per naming of viewcontrollers) then you can use prepareforsegue to set flag! If you are popping to VC2 from VC3 then you can use delegate and protocol or NSUserDefaults for store or set the flag!
Yes, it is possible, you can choose to hide the views(let say firstView) you don't want to display by simply hiding that view(firstView) or if your other view's(let say secondView) constraint are been set with respect to the view(firstView) which you want to hide, then you may change the height of view(firstView) to zero.
In this way you will be able to hide the views you want to hide. You just need to decide which view you need to hide and then change the constraint or hide the view when going to that viewController.
To give some context, I have logic that programmatically decides what view controller to insert into the navigation controller. For example:
If(true){
MyViewController * MyObject = [[MyViewController alloc]init];
myNavigationController = [[UINavigationController alloc]initWithViewController:MyObject];
else {
MyOtherViewController * MyOtherObject = [[MyViewController alloc]init];
myNavigationController = [[UINavigationController alloc]initWithViewController:MyOtherObject];
}
self.tabBarController.viewControllers=[NSArray arrayWithObjects:myNavigationController,nil];
Hopefully that illustrates my point of how I insert views inside of navigation controller. Now onto my problem:
I have an action listener with a button inside of "MyViewController" that essentially replaces the navigation/tab bar index when the user clicks the button. Is it possible to update a navigation/tab bar index with just a button?
MyViewController.m
- (IBAction)MyActionListener:(id)sender {
MyOtherViewController *MyOtherObject = [[MyOtherViewController alloc] initWithNibName:#"MyOtherViewController" bundle:nil];
[self.view insertSubview:MyOtherViewController.view atIndex:2];
}
When I do this, I get a crash EXEC_BAD_ACCESS I'm just wondering if my implementation/approach is wrong. I noticed this question: Update UITabBar Views?
However, doesn't seem to fit the results I am looking for. Hopefully I am clear. Thanks!
Yes it is possible to switch your views on button click with navigation.
You currently in VC1 , you have other two vc VC2 & VC3 and on button click you choose VC2 or VC3 but you did not change the VC1 place.
I make a Tabbed Application using storyboard template, two view controllers are embedded.
This is what I want to do: in the first viewController, let TabBar to select the second viewController programmatically.
The first viewController is a tableViewController, shows a list of items, and each item will push to a detailViewController. In the detailViewController, I edit some information and save the item. Then I want app to show the second ViewController, which is a tableViewController shows saved item.
Usually, we can use [TabBarController setSelectedIndex:1]; to select the second viewController.
However, since this is a storyboard template application, so many code are hidden behind. So I cannot get the TabBar instance in the first viewController, and use setSelectedIndex method.
This is what confuses me...
And now, I have found the solution for this problem. My answer is below.
I have figured out how to solve this problem.
First I add new a class: MyTabBarController.
Then, in storyboard, select the Tab Bar Controller, in identity inspector panel, set the custom class to this new class.
For the first viewController class, add a property
#property (nonatomic, weak) UITabBarController *tabBarController;
Then add - (void)viewDidAppear:(BOOL)animated in MyTabBarController class:
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
UINavigationController *navigationController = [self.viewControllers objectAtIndex:0];
FirstViewController *firstViewController = (FirstViewController *)navigationController.topViewController;
firstViewController.tabBarController = self;
In this way, I pass the tabBarController instance to the firstViewController, so, in the firstViewController, I can call [tabBarController setSelectedIndex:1];
Storyboard gives me a visual interface, however, it hides so many things behind.
I have a view with 3 buttons and a tabbar controller that contains 3 views. I am using the storyboard. I want go from my view to a specific view from the tabbar controller. When I create a segway to the destination view, the tabbar is not included.
The only way I find out is to create a segway to the tabbar controller itself, but then by default the first view is been shown.
Thanks in advance!
Yess!! I got the solution. Do the following:
In you're .h file:
#property (strong, nonatomic) UITabBarController *tabController;
In you're .m file:
#synthesize tabController;
tabController = [self.storyboard instantiateViewControllerWithIdentifier:#"tabbar"];
The selected index is the tab you want to go
tabController.selectedIndex = 1;
[[self navigationController] pushViewController:tabController animated:YES];
I currently have a view set up as the following:
#interface BlogViewController : UIViewController <UITableViewDelegate, UITableViewDataSource> {
UITableView *mainTableView;
}
#property (nonatomic, retain) UITableView *mainTableView;
As you can see, it has a UITableView inside of it that I load all of my data to. However, when I call the following function:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
SingleBlogViewController *viewController = [[SingleBlogViewController alloc] init];
[self.navigationController pushViewController:viewController animated:YES];
//[self presentModalViewController:viewController animated:YES];
[viewController release];
}
nothing happens. For some reason my UITableView inside of my UIViewController isn't pushing the view. Is this because it isn't a UITableViewController? I tried changing it to that, and it still didn't work.
Am I missing something here?
I found the first parts of this blog post useful for showing how to create and use a UINavigationController programmatically without Interface Builder.
Some of the things I wish the docs and tutorials would have stressed to me:
When you create the UINavigationController you get a UIView and UINavigationBar for free (i.e. you don't need to separately add them and figure out how to hook them together).
You add the myUINavigationController.view property as the "main" view and then push/pop UIViewControllers onto the UINavigationController and they will automatically show up as visible in the myUINavigationController.view UIView.
When you push a UIViewController onto a UINavigationController, the UIViewController.navigationController is filled in. If you haven't pushed the view onto the navigation controller, I'm guessing that property is empty.
The time/place to programmatically add buttons to the UINavigationBar is not when and where you construct the UINavigationController, but rather by the individual UIViewControllers when they are loaded as you push onto the UINavigationController.
I only had to add a "Done" button to the UINavigationController's UINavigationBar in the viewDidLoad method of the first UIViewController pushed onto the UINavigationController. Any UIViewController I pushed on top of that first view automatically had a "back" button in the to navigate to the covered up UIViewController.
If you set the title property of your UIViewController before you put it on the UINavigationController's stack. The UINavigationBars title will be the title of your view. As well any "back" buttons will automatically name the view you are returning to instead of generically saying "back".
Please visit "How to add UINavigationController Programmatically"
Please visit above link & get all information regarding UINavigationController.
UINavigationController is a subclass of UIViewController, but unlike UIViewController it’s not usually meant for you to subclass. This is because navigation controller itself is rarely customized beyond the visuals of the nav bar. An instance of UINavigationController can be created either in code or in an XIB file with relative ease.