I am working on a projects but have different screens. As there is more complexity I have told to create 2 projects then to marge it into 1 app.
So basically I have 2 projects lets name it as A and B. and both have 2 different storyboards.
Now I want these to projects to marge and when app fires storyboard from project A should show and there is button in project A and upon tapping it should show project B.
How can I achieve this. Can any buddy there help me..
I am not sure about this , but you can try this
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"YourStoryboardName" bundle:nil];
YourViewController *objViewController = [storyboard instantiateViewControllerWithIdentifier:#"YourViewController"];
[self.navigationController pushViewController:objViewController animated:YES];
Related
Apple now wants us to use "scenes" rather than windows and screens to display content in for iPad and iPhone. Now having added the support for scenes I seem to have lost the ability to target iPad or iPhone with Storyboards?
I set my scenes inside plist like this:
This was copied from a new project, as Apple seems to have forgotten to document how to add scenes to an existing app. Another example of Apple not documenting sufficiently!
Now I seem to have lost the ability to use different storyboards for iPad from iPhone.
Whilst I could use the same storyboard for the iPad that I use with the iPhone my app looks better with the dedicated interface I have for the iPad because I use the extra real estate it offers to give a better end user experience. iPhone is fine, the interface is best suited to a small display but looks barren on an iPad.
Help!
Now I seem to have lost the ability to use different storyboards for iPad from iPhone
It's quite simple (and, as you say, not documented). You need two completely separate scene manifest entries in your Info.plist, i.e. UIApplicationSceneManifest and UIApplicationSceneManifest~ipad. They just specify different UISceneStoryboardFile values, and you're all set just as before scenes came along.
There may be a better way to do this, but searching I couldn't see anybody else covering this. Therefore, I'm giving my solution which has been accepted by the App Store here for others to review, use, improve upon, and most importantly, not waste any time on a goose chase looking for a solution that may not exist!
The way I got around this was to add another storyboard and view controller just to handle the decision if it's a iPhone or iPad, and then immediately load up the targeted storyboard. I called this "entry decision". The only issue was when closing the subsequent views you have to ensure that you're doing it correctly or you'll end up back at the "entry decision". And with a blank view, your end user could be stuck. Therefore, to ensure a user can never really be stuck I put buttons in that view so they can manually navigate should it show up if there's a change by Apple further down the line that we don't know about. Best to cover it now.
Step 1, create an new storyboard, "entry decision":
Because I'm a nice person I explain to the user it's an error and apologise. I also give them two buttons, iPad and iPhone. In theory, if all goes well, the end user will never see this, but at no cost to us it's better to cover this possibility.
Step 2, as soon as the view controller is loading get it to move to the right storyboards we actually want.
-(void)viewDidLoad {
// Need to decide which storyboard is suitable for this particular method.
// Loading from class: https://stackoverflow.com/questions/9896406/how-can-i-load-storyboard-programmatically-from-class
if ( [UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad )
{
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard_iPad" bundle:nil];
ViewController *detailViewController = [storyboard instantiateViewControllerWithIdentifier:#"myViewController"];
[self.navigationController pushViewController:detailViewController animated:YES];
}
else
{
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil];
ViewController *detailViewController = [storyboard instantiateViewControllerWithIdentifier:#"myViewController"];
[self.navigationController pushViewController:detailViewController animated:YES];
}
}
- (IBAction)pickediPhone:(id)sender {
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil];
ViewController *detailViewController = [storyboard instantiateViewControllerWithIdentifier:#"myViewController"];
[self.navigationController pushViewController:detailViewController animated:YES];
}
- (IBAction)pickediPad:(id)sender {
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard_iPad" bundle:nil];
ViewController *detailViewController = [storyboard instantiateViewControllerWithIdentifier:#"myViewController"];
[self.navigationController pushViewController:detailViewController animated:YES];
}
There's nothing really special about this as it is a mix of detecting which device and then loading the right storyboards. And for full disclosure, I include a reference back to the original code I used for loading those storyboards.
The additional two methods are just the button presses, shown here for completeness.
Step 3, update the scene configuration inside plist to target Entry Decision instead of Main.
You're targeting a different storyboard, hence this needs updated.
Step 4, returning back to your main screen.
In my app, I have a welcome screen, and then table views or other views depending on which it is. Some types work find without any issues, but as I'm using a navigational controller I need to return correctly. Therefore, this one works best for the final "back" command to the main screen:
[self.navigationController popViewControllerAnimated:YES];
Other options either went back to the Entry Decision (the fault we covered just in case) or did nothing:
[self.navigationController popToRootViewControllerAnimated:YES];
[self dismissViewControllerAnimated:YES completion:NULL];
And that is how I'm able to use my existing storyboards, which have been tweaked perfectly for iPhone and iPad over the years of this app's life, and still be able to support Apple's desire to move to scenes. My app needed to use scenes for another purpose, therefore I had no option but to go this route. I went through many attempts to try and trap the scenes as they're getting loaded, but the initial scene seems to get loaded without you, the programmer, getting any options in how it should be or which one to use. You need this pre-view controller to give you that functionality back, and it is one solution which is active in the App Store now.
Be nice.
I wanted to have separate storyboard files for every UIViewcontrollers in my iOS app.
So how can we assign different storyboards for each controllers? Also how do we do navigation between those?
This I am doing to avoid svn conflicts while so many people working on UI.
get a reference to the storyboard...
UIStoryboard *someStoryboard = [UIStoryboard storyboardWithName:#"NameOfYourStoryboard" bundle:nil];
then instantiate either the initial viewcontroller from that storyboard...
UIViewController *initialViewController = [someStoryboard instantiateInitialViewController];
or some other viewcontroller identified by it's storyboard identifier...
UIViewController *someOtherViewControllerFromTheStoryboard = [someStoryboard instantiateViewControllerWithIdentifier:#"SomeViewControllersStoryboardIdentifier"];
after that you can simply push (within a navigation controller) or present the new viewcontroller.
since iOS 9.0 you can even connect storyboards via storyboard references in the storyboard itself:
https://developer.apple.com/library/prerelease/ios/recipes/xcode_help-IB_storyboard/Chapters/AddSBReference.html
Keeping different storyboards for different modules is good approach. You can achieve the navigation between storyboards as follows:-
Suppose you are in A view controller and want to push another view controller named FabIdeaDetailViewController which is present in storyboard named FabIdeas:-
FabIdeaDetailViewController *horizontalListController = (FabIdeaDetailViewController*)[UIViewController instantiateViewControllerWithIdentifier:#"FabIdeaDetailViewController" fromStoryboard:#"FabIdeas"];
[self.navigationController pushViewController:horizontalListController animated:YES];
Now for pushing another view controller named WishlistViewController which is present in storyboard named Wishlist:-
UIViewController *WishlistViewController = [UIViewController instantiateViewControllerWithIdentifier:#"WishlistViewController" fromStoryboard:#"Wishlist"];
[self.navigationController pushViewController:WishlistViewController animated:YES];
I created a workspace and added two projects in Xcode workspace. One new and one existing. I want to access a storyboard of an existing project within a tap of a button in new project. Can I do that?
Existing project is linked with a lot of libraries and one of them is Tapku library. It works fine, but I want to have a new project and some buttons there, that when I tap a button I access an existing projects storyboard and then work with that so called application.
thank you.
This is what I tried to do:
UIStoryboard *sb = [UIStoryboard storyboardWithName:#"Main_iPad" bundle:nil];
UIViewController *vc = [sb instantiateViewControllerWithIdentifier:#"LoginView"];
vc.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentViewController:vc animated:YES completion:NULL];
and I have error:
Could not find a storyboard named 'Main_iPad' in bundle NSBundle "somePath/Application1.app (loaded)
This storyboard is in Application2 Project.
I have two ios app one variant of the app is for the teachers and second version is for the students.Student version is live from the last two year on the app store.This version is non-ARC project .Now developed the teacher variant of the app .this version is using the storyboard and have the ARC.
My problem is that in the student version application is tabbar based and tabbar is declared in the app delegate .where as in the teacher version the application is based on heavily customised uinavigation controller like the side slide in menu ;which is declared in app delegate too.Now my problem is how can i combine these two project into one iPhone app.
Both teacher and students can be identify based upon the login.
I would try to re-work the student version into a storyboard (a separate one from the teachers version) and update it to ARC. Then, base on the login results (student or teacher), load the appropriate storyboard. So after you have the results of the login, you could do something like this:
UIStoryboard *storyBoard;
if (isStudent) {
storyBoard = [UIStoryboard storyboardWithName:#"MainStoryboard_student" bundle:nil];
}
else {
NSLog(#"teacher!");
storyBoard = [UIStoryboard storyboardWithName:#"MainStoryboard_teacher" bundle:nil];
}
UIViewController *initViewController = [storyBoard instantiateInitialViewController];
[self.window setRootViewController:initViewController];
In order to make sure your app will replace the one in the store, make sure you keep the same bundle ID for the new combined app as you had for the student version currently in the store.
If you do not want to convert the student version files to ARC, you can convert the project to ARC, but flag the student classes that have not been converted to arc with the -fno-objc-arc flag
Basically, click on the project file, select your target, select the Build Phases tab, and for each of the old project files that do not use ARC, add -fno-objc-arc in the Compiler Flags field in the Compile Sources section.
If both teachers and students can be identified at the login stage, to solve this problem you most likely would need create a unified login page (root view controller) in your AppDelegate. Then after the user logins you determine what part of app would be more appropriate and show the next view controller embedded in UINavigationController or UITabBarController.
you can can make student project compatible to ARC by adding compiler flag -fno-objc-arc to all class files of student project.
remove auto loading of storyboard from the project settings, in AppDelegate define the logic for loading the rootview.
if (isStudent) {
UIViewController *rootViewController = [[UIViewController alloc] init];//whatever you appdelegate code for student is
[self.window setRootViewController:rootViewController];
}
else {
NSLog(#"teacher!");
UIStoryboard *storyBoard;
storyBoard = [UIStoryboard storyboardWithName:#"MainStoryboard_teacher" bundle:nil];
UIViewController *initViewController = [storyBoard instantiateInitialViewController];
[self.window setRootViewController:initViewController];
}
My project contains over 60 View Controllers and Xcode is very laggy when loading the storyboard.
How can I resolve this without switching to xibs? I am using Xcode 5.1 and iOS 7.x
Problem
Putting all of your ViewControllers in one Storyboard will significantly slow down Xcode (which renders XML to show your ViewControllers) if the number of the ViewControllers is above 10. Storyboard is not the place to put all of your views, because as its name suggests a board of a specific story.
Solution
Make multiple Storyboards with 5 or 6 ViewControllers each, where you can avoid rendering hell of multiple ViewControllers. You can divide your Application on different boards named by group functionality like LoginStoryboard, UserProfileStoryboard, etc.
You can instantiate a storyboard and present a specific controller by the code below:
UIStoryboard *storyBoard = [UIStoryboard storyboardWithName:#"Your Storyboard Name" bundle:nil];
UIViewController *viewController = [storyBoard instantiateViewControllerWithIdentifier:#"Your Controller ID"];
[self presentViewController:viewController animated:true completion:nil];
Keep views in more than one storyboard. It's not the problem if not every controllers are connected with segues. There is no good way to keep a large number of views in a storyboard, in addition to working on a better computer.