Tutorial screens for app - ios

Hi I have found an awesome tutorial to show an overview of my app. how would you return back to the main app after this tutorial view has been viewed?
Here is the location of the tutorial and all the source code.
My app views are in storyboard and I have a navigationcontroller in which my rootviewcontroller is held.
I'm hoping to return to the rootviewcontroller of the navigation controller after the last page of the tutorial view is displayed.
Thank you if you can help.
Here is my storyboard:
The code I used to load the tutorial is this in AppDelegate:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
/* This loads up the xib but I can't get back to the storyboard rootViewController */
if (tutorialHasBeenSeen == false) {
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
self.appViewController = [[APPViewController alloc] initWithNibName:#"APPViewController" bundle:nil];
self.window.rootViewController = self.appViewController;
[self.window makeKeyAndVisible];
tutorialHasBeenSeen =TRUE;
}
return YES;
}
Would I try to pop to the rootView in the AppViewController.m in the method:
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController {
NSUInteger index = [(APPChildViewController *)viewController index];
index++;
if (index == 5) {
return nil;
}
return [self viewControllerAtIndex:index];
}

Have you tried using
[self.navigationController popToRootViewControllerAnimated:YES];
EDIT
Now that I see what you are trying to do, I would recommend changing your approach:
Instead of choosing if you should present the Tutorial in the didFinishLaunchingWithOptions method in the application delegate, why don't you always start on your application's First view controller, and here determine if the user should be displayed with a Tutorial or not, in that way you can invoke the Tutorial view controller inside your First view controller in your established navigation way of displaying hierarchical content.
The reason that you can't go from Tutorial to your First view controller is because you are assigning the Tutorial as your window view controller directly from the app delegate. So there is no way of going 'back' from Tutorial to your First view controller, to fix this I can think on two options,
At a desired moment change the window view controller of your application to be your First view controller instead of the already assigned Tutorial view controller. Which, as you may be guessing, is a tricky and just not clean way of doing this.
Set up a proper navigation hierarchy in your app, so First view controller should present your Tutorial view controller. And after, at a desired moment you simply dismiss or pop your Tutorial and get back to your First view controller.
As a conclusion,
1.Don't present your Tutorial from the AppDelegate, so leave the following method clean or as necessary but to perform other actions.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
return YES;
}
2.From the view controller that will be your First view controller, invoke your Tutorial using segues or by code applying your desired logic for determining when a user should see the tutorial. If done properly when the app starts and the Tutorial appears it will be invisible that you are first displaying the First view controller
3.From your Tutorial view controller and at the desired moment dismiss or pop (will depend on your navigation) your view controller so you can go back to the First view controller

Related

How to programmatically show a controller that has a navigation controller and tabbar controller as defined in a storyboard?

I'd like to show the tableview controller embedded in the navigation controller from the app delegate.
The reason I need to do this is I'm building a wrapper over an api, so to login I direct users to a relevant webpage where they can login to grant my app access to their credentials, then they are sent to a relevant url end point which triggers my app. At this point I want to load the tableviewcontroller in the navigation and tabbarcontroller.
Is it possible to define multiple entry points on storyboards?
A screenshot of my current storyboard configuration is shown here:
https://www.dropbox.com/s/6wfo5werrs6vwy1/Screenshot%202014-10-09%2008.43.15.png?dl=0
You cannot define multiple entry points on storyboards. To achieve this, you should use [UIStoryboard instantiateViewControllerWithIdentifier:] and set the view controller to root view controller in your app delegate based on your condition.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
NSString *identifier
if (/* path A */){
identifier = #"vc1";
} else {
identifier = #"vc2";
}
UIViewController *vc = [storyboard instantiateViewControllerWithIdentifier:identifier];
self.window.rootViewController = vc;
[self.window makeKeyAndVisible];
}

UINavigation controller isn't notified about orientation events correctly

I am working on iOS 6.1 and 7.0. The behavior is the same for both of them. The root view controller is UIVeiwController. It has a property UINavigationViewController which manages all the displayed controllers in my app. I have subclassed UINavigationController and overloaded shouldAutorotate and supportedInterface rotations methods to get correct orientations of each controller pushed in it.
What I want: Push in navigation 3 controllers, the second controller should be only in portrait orientation.
What I get: When I am pushing second controller it is still in landscape mode, despite it's supportedInterfaceOrientation method returns Portrait mode, then push third controller and put simulator or device in landscape mode and pop to my second controller, here is most interesting it goes away from the screen...
My guess Apple documentation says that only most top view controller will be notified about rotations, so when I make navigation controller root it works correct when I make pop from third controller to second but still doesn't work when pushing from first to second. Any way I need to solve this issue with my structure when navigation controller is only a property of root view controller.
Here is a link to project https://github.com/Trubianov/Navigation.git
The problem is that the new workflow makes rotation methods to be checked only once when the controller is presented, that's why it's not working.
When pushing things inside a UINavigationController (or any other UIViewController container) you can decide on the child UIViewController what orientation it supports, and the OS will make it work for you.
My suggestion: unless you have some custom code that you MUST have in your UINavigationController subclass, you should remove it entirely and move the rotation checks to the child view controllers you are presenting
Here is the solution. If you put UIViewController to window.root, and your navigation controller is just a property of the root controller, than your navigation won't get appropriate callbacks from UIApplication, so u MUST add navigation as child view controller to your root controller.
My code snippet:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.window.backgroundColor = [UIColor whiteColor];
MyNavigationController *navController = [[MyNavigationController alloc] initWithRootViewController:[ViewController1 new]];
MainViewController *main = [MainViewController new];
main.myNavigationController = navController;
[main addChildViewController:navController];
self.window.rootViewController = main;
[self.window makeKeyAndVisible];
return YES;
}
Also is needed to override following methods in MainViewController.
- (BOOL)shouldAutorotate
{
return [self.myNavigationController.topViewController shouldAutorotate];
}
- (NSUInteger)supportedInterfaceOrientations
{
return [self.myNavigationController.topViewController supportedInterfaceOrientations];
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return [self.myNavigationController.topViewController preferredInterfaceOrientationForPresentation];
}

can we use table based navigation in single view application?

I have created single view iOS application with some basic functionality. and added the table view in simple view controller now I wanted to use table view with row navigation like(pushcontroller and popcontroller) is that possible and if it is, how we can set that.
If you need full support for push/pop operation, I would use a navigation controller.
On the other hand, you could simply present your detail view controllers when a table row is tapped:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
MyViewController* detailController = <CREATE THE VIEW CONTROLLER>;
[self presentViewController:detailController animated:YES completion:NULL];
}
In this case, your detailController will need to implement a sort of navigation bar or other mechanism to let the user dismiss the controller (through dismissViewControllerAnimated:completion:) and go back to the table view. (Using a navigation controller would instead take care of this in a canonical way.)
One major drawback of the simpler solution based on presenting/dismissing is the fact that all the view controllers presented this way are dismissed at once, so you cannot have multiple levels of navigation.
EDIT:
To add a navigation controller to your app, simply do something like this:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
...
MyViewController *myViewController = [[MyViewController alloc] initWithNibName:nil bundle:nil];
...
self.navigationController = [[UINavigationController alloc] initWithRootViewController:rootViewController];
self.window.rootViewController = self.navigationController;
[self.navigationController pushViewController:myViewController animated:YES];
...
[self.window makeKeyAndVisible];
return YES;
}
At the moment, your didFinishLaunchingWithOptions method should use the addSubview method to make your main view controller (named MyViewController in my example) visible. You can replace that call by the code above to instantiate the navigation controller and push on to it your main view controller.
Alternatively, you could create a new Xcode project using the navigation-based template and move all of your source files over.

iOS Storyboard Switch to a View that has no segue on AppDelegate

I have a one time agreement view that will only show up when user launches app first time.
I use storyboard IOS 5.1 and My rootview is a navigationviewcontroller. My agreement view has no connection with navigation controoler I just want to present a modalview pop up then dismiss the view:
I use following code but it doesn't do anything app just continues and launches navigationviewcontroller I put flags, yes app enters the if statement. :
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
if(login==ok){
UIStoryboard *storyboard = [UIApplication sharedApplication].delegate.window.rootViewController.storyboard;
UIViewController *loginController = [storyboard instantiateViewControllerWithIdentifier:#"AgreementViewController"];
[self.window.rootViewController presentModalViewController:loginController animated:YES];
}
return YES;
}
How can I switch a viewcontroller that has no connection to storyboard and dismiss it?
In the app I've been working on last weekend I had a similar situation. I wanted to show a seperate storyboard the first time for a guided setup.
My code looked pretty much the same as yours and it gave me a warning when I was debugging it.
This was because of the fact that the rootViewController I was trying to present my one-time ViewController on, isn't visible at this point in the app.
So, instead of presenting my one-time view controller "on" the rootViewController, I decided to set my one-time view controller as the rootViewController.
In your case it would be something like:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
if(login == ok) {
UIStoryboard *storyboard = [UIApplication sharedApplication].delegate.window.rootViewController.storyboard;
UIViewController *loginController = [storyboard instantiateViewControllerWithIdentifier:#"AgreementViewController"];
[self.window setRootViewController:loginController];
}
return YES;
}
To dismiss it, you could probably add a segue from your one-time view controller to your first view controller or you could use code similar to the one in your question.
Another approach would be to do the check and view switching in your first "normal" view's viewDidAppear, instead of in the AppDelegate.
Hopefully this will point you in the right direction.

Navigation Controller is null

I have a split-view app that allows a user to select and display a thumbnail of a chosen image. I have placed a UIButton in the detailViewController using Interface Builder. When this button is pressed, I would like to have it change to a full screen view of the image. I have set up a new View Controller, called FullViewController and thought I had everything connected. The problem is that the navigation controller is null. I adjusted the AppDelegate.m to the following:
AppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after app launch.
// Set the split view controller as the window's root view controller and display.
self.window.rootViewController = self.splitViewController;
UINavigationController *nvcontrol =[[UINavigationController alloc] initWithRootViewController:fullViewController];
[window addSubview:nvcontrol.view];
[self.window makeKeyAndVisible];
return YES;
}
This is the function in the DetailViewController.m which is called when the button is pressed. The navigation controller comes up null in here.
//Function called when button is pressed - should bring up full screen view
- (IBAction) pressFullViewButtonFunction: (id) sender{
//viewLabel.text = #"Full View";
if (fullViewController == nil){
FullViewController *fullViewController = [[FullViewController alloc] initWithNibName:#"FullViewController" bundle:[NSBundle mainBundle]];
NSLog(#"fullViewController is %#", fullViewController);
self.fullViewController = fullViewController;
}
NSLog(#"self.navigationController is %#",self.navigationController);//this is null
[self.navigationController pushViewController:self.fullViewController animated:YES];
}
I'm not sure how to fix this. I've tried adding in the couple lines in the AppDelegate, but when it runs, the table in the root view doesn't show up and it no longer properly switches between portrait and landscape views.
I have the rest of the code readily available if that would help clarify. Just let me know!
Thanks.
From the code you post it is not possible to identify the problem, but two common reasons for self.navigationController to be nil are:
you did not push the object behind self on to the navigation controller in the first place; indeed it seems so, since the navigation controller is added as a subview of the split view controller; possibly you mean the opposite... not sure...
(sub-case of 1) you showed the object behind self using presentViewControllerModally.
When I say "the object behind self" I mean the instance of the class where pressFullViewButtonFunction is defined.
If you need more help, post the code where you push your controllers on to the navigation controller...
On a side note, if you do:
UINavigationController *nvcontrol =[[UINavigationController alloc] initWithRootViewController:fullViewController];
and nvcontrol is not an ivar, then you have a leak.
Hope this helps...

Resources