I want to create a Master-Detail Application which contains 3 Views in a master-detail hierarchy.
First View=>Second View=>Third View
When I create a Master-Detail Project, XCode creates two ViewControllers; a Master View controller and a Detail View Controller... I want to add a third ViewController to project and open this new View from a TableView in DetailView Controller.
I am little confused about this, I added a new UIViewController class to my project but I can't understand how I create a relationship between my new view and DetailView Controller?
If you would like to use DetailController -> YOur next Controller you can use it like this
Open your storyboard and add there a view controller
Set an unique title to this view controller - U can find this option under like shield icon in the right menu. Set the title whatever you want (lets say my_detailed_controller)
And then in case you want to go from the detail view controller to the further more detailed controller you call this snippet :
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle: nil];
YOURVIEWCONTROLLER *lvc = [storyboard instantiateViewControllerWithIdentifier:#"my_detailed_controller"];
[self.navigationController pushViewController:lvc animated:YES];
Related
There is problem in view hierarchy. Here is flow of my app.
When app starts View Controller "A" is Visible. After that storyboard "B" is loaded through "StoryBoard Reference (Push)" ,Where another navigation controller is present and Home screen is loaded. On Click of Menu button in Home screen Side panel is visible.
Now When i click on side panel menu items view Controller "B" is pushed. This View Controller is Pushed Under Home screen and is not Vsible.
Help View contoller is visible under Home controller. I want Help View Controller should come on top of Home controller.
I dont understand what issue is coming..
Any Help will be appreciated..
If you are pushing view controller from side panel shows in image, will never push because it is not in navigation controller.
the answer depends on how you showing your side menu but from assumptions
what you need to do is to set root view controller or keep reference of navigation controller and push from there
If you are presenting side menu then it is not on navigation controller so you should first dismiss this side menu and on the completion of it you should push new view controller (says B or Help). I am writing my code snippet that i am using in my project for demonstration,
- (IBAction)settingClick:(id)sender {
SettingViewController *svc = [self.storyboard instantiateViewControllerWithIdentifier:#"settingsScreen"];
[self dismissViewControllerAnimated:NO completion:^{
[self.vc.navigationController.navigationController pushViewController:svc animated:YES];
}];
}
Above method push setting view controller on current navigation controller after dismissing side menu
Now important thing is self.vc this is the object of previous viewcontroller (Home controller in your case i think) on which side menu was presented.
So my SideMenuViewController has a property like,
#property (nonatomic,strong) UIViewController *vc;
which i am setting with self from previous view controller (in your case from Home view controller) something like,
SideMenuViewController *smvc = [self.storyboard instantiateViewControllerWithIdentifier:#"sideMenu"];
smvc.modalPresentationStyle = UIModalPresentationOverCurrentContext;
[self presentViewController:smvc animated:NO completion:^{
smvc.vc = self;
}];
And i have used [self.vc.navigationController.navigationController pushViewController:svc animated:YES]; i.e. two navigation controller to push because i have two navigation controller in my view hierarchy to push this new view controller.
You can manage that as per your setup that how many navigation controller you have !!
Hope this will help :)
After digging a lot, I found solution for this.
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Home" bundle: nil];
RootController *someViewController = [storyboard instantiateViewControllerWithIdentifier:#"RootController"];
[self.navigationController pushViewController:someViewController animated:YES];
I have set another navigation controller as root ViewController of the window and it worked for me.
Thanks.
I added a Navigation Controller to my storyboard and it appears like so:
Now in the table view controller, I gave the TableViewController a storyboard id and class to a TableViewController Controller
When I run my app, I don't see the Navigation Bar at the top. This has been extremely frustrating and can't find a solution anywhere. PLEASE HELP
To get to the scene, someone clicks a button and this code runs and it goes to my Table View Controller:
UIStoryboard *storyBoard = [UIStoryboard storyboardWithName:#"Storyboard" bundle:nil];
LHFileBrowser *LHFileBrowser = [storyBoard instantiateViewControllerWithIdentifier:#"FileBrowser"];
[self.navigationController pushViewController:LHFileBrowser animated:YES];
[self presentViewController:LHFileBrowser animated:YES completion:nil];
The error is in your code.
If you want to (modally) present a view controller when the user presses a button, you need to present the navigation controller (which will contain the table view controller), not the table view controller itself.
Right now, you're presenting the view controller, which won't show it being embedded in a navigation controller.
Also, you're mixing up two different approaches, by trying to push a view controller onto a navigation controller stack, and also presenting the view controller.
Code Sample:
Here's what you apparently mean to do:
UIStoryboard *storyboard = self.storyboard;
UINavigationController *navigationController = [storyboard instantiateViewControllerWithIdentifier:#"MyNavigationControllerID"];
LHFileBrowser *rootViewController = [navigationController topViewController];
// Configure your LHFileBrowser view controller here.
rootViewController.someProperty = ...;
// Modally present the embedded view controller
[self presentViewController:navigationController animated:YES completion:nil];
If you want to change the presentation or transition style, you can set those details in your storyboard.
You didn't explain why you had to programmatically add buttons, but Storyboard segues would have instantiated and presented an embedded view controller for you, without you having to have done it in code.
The more you can do in Storyboard, the less code you have to maintain, support, and update, and the more likely your app will still work properly when a new SDK is released.
Update:
The better way to do this is to let Storyboard do it for you, by adding a segue from the button to the navigation controller that you want to present.
I have two storyboards in the same ios application.
Storyboard 1 is the login.storyboard.
Storybaord 2 is the processing.storyboard.
login.storyboard has the following scenes:
1) welcome
2) login
processing.storyboard has
1) start
2) images
3) description
4) finish
login.storyboard handles login whilst processing.storyboard creates and object for uploading.
My understanding of the stack is as follows:
Navigate from welcome to login gives:
1:[welcome]-[login.storyboard]
2:[login]-[login.storyboard]
after login I push the processing.storyboard using
- (void) pushStory: (NSString *) story {
UIStoryboard *settingsStoryboard = [UIStoryboard storyboardWithName:story bundle:nil];
UIViewController *initialSettingsVC = [settingsStoryboard instantiateInitialViewController];
initialSettingsVC.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
[self presentViewController:initialSettingsVC animated:YES completion:nil];
}
the stack should now be:
1:[welcome]
2:[login]
3:[start]
I might get to description in the workflow before I decide to click logout (available on each page), my stack at this point would be
1:[welcome]-[login.storyboard]
2:[login]-[login.storyboard]
3:[start]-[processing.storyboard]
4:[images]-[processing.storyboard]
5:[description]-[processing.storyboard]
logout should take me back to [welcome], my question is with the storyboards how would I clear the stack back to [welcome] and ensure the login.storyboard is current.
There's a gap in my knowledge here, as I've just gotten back into iphone dev after 6 years or so and not seen these before.
I had thought of just pushing login.storyboard onto the stack but that would just make the stack continue to grow instead of clearing it out
Use unwind segues.
Add this method in [welcome]:
-(IBAction)reset:(UIStoryboardSegue *)segue
{
NSLog(#"Back to Welcome");
}
In Interface Builder, create UIButtons in [start], [images] and [description] then link each of these buttons to the green "Exit" button of their respective viewControllers and select reset: in the pop-up menu that appears.
(See WWDC 2012 session video "Adopting Storyboards in Your App" for more details about unwind segues [starts at 38 minutes].)
You can pop back to any arbitrary point in the stack, for example
[self.navigationController popToRootViewControllerAnimated:YES]; // all the way back to the first view controller
[self.navigationController popToViewController:self.navigationController.viewControllers[1] animated:YES]; // back to the second view controller
[self.navigationController popViewControllerAnimated:YES]; // back to the previous view controller
This answer assumes that storyboard 1 has
navigation controller
welcome view controller
login view controller
and storyboard 2 has
navigation controller
start view controller
images view controller
description view controller
finish view controller
Note that the navigation controller in storyboard 2 is never actually instantiated but is needed so that the other view controllers in storyboard 2 can be connected by segues. When navigating from the login view controller to the start view controller the code should look similar to this
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"SecondStoryboard" bundle:nil];
UIViewController *vc = [storyboard instantiateViewControllerWithIdentifier:#"ControllerC"];
[self.navigationController pushViewController:vc animated:YES];
Note that this doesn't instantiate the initialViewController since that's the navigation controller, and we don't want another navigation controller. Instead, give the start view controller a Storyboard ID under the Identity inspector, and then instantiate the start view controller directly. After instantiating the start view controller, push it onto the existing navigation controller. You may want to hide the back button if you don't want the user to navigate back to the login view controller.
I am trying to accomplish the following:
What I would like to do is:
1.) When the user clicks on a button in UIViewController, it will retrieve a list of items.
2.) The items will then be displayed in UITableView.
3.) Lastly the number of items will be displayed on the third view (not initiated by UITableView)
All the above I manage, except that I would like to wrap all these controllers in a customized tab bar controller. But the data is not being passed from the UIViewController to the UITableView or the other View. I am using Storyboard, I hooked up tab bar controller and the other 3 controllers there as view controllers. I have tried instantiating UITableView and the UIView controllers using UIStoryboard method and creating instances of these controllers and send the data to them, the controllers are shown in tab bar controller, but data is not. I am not using Segue, by the way. Am I missing something here?
Thanks.
CODE:
UITabBarController tabBarController = (UITabBarController) self.window.rootViewController;
UIStoryboard *storyboard1 = [UIStoryboard storyboardWithName:#"MainStoryboard_iPhone" bundle:[NSBundle mainBundle]];
mainViewController *mainController = (mainViewController*)[storyboard1 instantiateViewControllerWithIdentifier:#"mainController"];
UIStoryboard *storyboard2 = [UIStoryboard storyboardWithName:#"MainStoryboard_iPhone" bundle:[NSBundle mainBundle]];
tableViewController *tableview = (tableViewController*)[storyboard2 instantiateViewControllerWithIdentifier:#"tableviewController"];
UIStoryboard *storyboard4 = [UIStoryboard storyboardWithName:#"MainStoryboard_iPhone" bundle:[NSBundle mainBundle]];
resultController *mapView = (resultController*)[storyboard4 instantiateViewControllerWithIdentifier:#"resultView"];</code>
I have tried also creating the UI Table View and the result view controller in MainViewController and pass data to them (before they are even displayed), but no data is ever present when these controllers are displayed. I made sure I alloc and init these controllers properly and NSLog shows that the instance methods in these controllers are called, but still no data is shown, even though the controllers are displayed in tab bar view controller, when they are displayed.
UPDATE 2:
Now I am trying to do the following:
self.tableviewController = [self.tabBarController.viewControllers objectAtIndex:1];
self.resultViewController = [self.tabBarController.viewControllers objectAtIndex:2];
And when I call these:
NSLog(#"%#", [self.tabBarController class]);
NSLog(#"%#", [self.tableViewController class]);
NSLog(#"%#", [self.resultViewController class]);
They are all null.
Basically, I have 3 View Controllers hooked up as "view controllers" using storyboard to a UITabbarController. The main view controller (at index 0 in UITabbarController), from which I call the above, simply has one UIButton. Once pressed it will fetch a list of strings and send it to the Table View (at index 1 in UITabbarController) and on the last View Controller (at index 2 in UITabbarController) it will show just the number of strings as a result, which it receives from the Main View Controller, not from Table View.
I am not using any UINavigationController in my set up.
I would like to be able to fire off Table View and the Result View Controller before they are even displayed by clicking on the bar item tab on UITabbarController. By firing off I mean the data will be sent over to Table View and Result View even though they are not yet displayed.
The code you present is unnecessary and wrong for what you want to achieve. (Usually you should have one instance of UIStoryboard.) Read the docs.
You do not write anything about how you try to achieve the communication between the view controllers. There are several methods. But use delegation. Read the docs.
If you answer to a comment you should use the # character followed by the SO user name so he is notified about your updates.
Well I have read those posts and tutorials but they made me more confused:
url 1
quest 1
quest 2
What i want is to do this:
At the beginning my app, has a table view. when I press a row, it should take me to another view which has tabs.
What I did so far was these:
1) Created a navigation controller , and there is my tableview. When I press a row, a single view opens. In that view (with its own .xib file) I added tab bars items.
You can see pictures here:
But now, I don't know how to make it when pressing a tab bar item, to open a new view. I am trying to embed my view in a controller but I cannot.
2) Then I tried this:
Having my navigation controller as before and I added in storyboard a tabbar controller like in that picture:
But I cannot connect them. My first view is class "SkiCenter" and code I am using is:
SkiCenter *myDetViewCont = [[SkiCenter alloc] initWithNibName:#"SkiCenter" bundle:[NSBundle mainBundle]];
myDetViewCont.ski_center=[centers objectAtIndex:indexPath.row];
[self.navigationController pushViewController:myDetViewCont animated:YES]; // "Pushing the controller on the screen"
[myDetViewCont release]; // releasing controller from the memory
myDetViewCont = nil;
and I get SIGBRT that says something about .nib file for "SkiCenter".
Can you suggest a sollution in either 1 or 2?
just to make it more clear:
Solution 1:
pressing the row gets me to a single uiview named skicentermain. I have added several tabbaritems but I do not know how to make them open new views.
Sollution 2:
Inserted a tabbar controller. Its first tab is SkiCenter. But when pressing the row, I get a sigbart error. it says something about the nib file of SkiCenter.
If you decide to use storyboard you can simply put an identifier to any view controller from attributes inspector and then instantiate it with its id.
UIStoryboard * storyBoard = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil];
[[self navigationController] pushViewController:[storyBoard instantiateViewControllerWithIdentifier:#"ViewControllerID"] animated:YES];
It looks like your declaring your *myDetViewCont incorrectly. You called your nib SkiCenterMain, not SkiCenter. Also, what exactly is on SkiCenterMain? Is that a UITabBarController?
//SkiCenter *myDetViewCont = [[SkiCenter alloc] initWithNibName:#"SkiCenter" bundle:[NSBundle mainBundle]];
SkiCenter *myDetViewCont = [[SkiCenter alloc] initWithNibName:#"SkiCenterMain" bundle:[NSBundle mainBundle]];