view not in the window hierarchy - iphone

I have created a function in app delegate which i run from a view but when I comeback to run the function again it gives me
<ResultViewController: 0x757dfc0> on <ViewController: 0x71325c0> whose view is not in the window hierarchy!
Error
the app delegate code is opening a viewcontroller
code is
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
ViewController *view1 = [[ViewController alloc]initWithNibName:#"ViewController" bundle:nil];
[self.window setRootViewController:view1];
[self.window makeKeyAndVisible];
return YES;
}
-(void)specify
{
ResultViewController *res = [[ResultViewController alloc]init];
CATransition *transition = [CATransition animation];
transition.duration = 0.3;
transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
transition.type = kCATransitionPush;
transition.subtype = kCATransitionFromRight;
[self.window.layer addAnimation:transition forKey:nil];
[self.window.rootViewController presentModalViewController:res animated:NO];
}

Not running your code I am guessing it is because the window you are trying to add to does not exist on the view hierarchic, you are just creating views and adding them to the screen - you need to grab the actual screen itself.
Try something like
UIViewController *presentController = [[[[UIApplication sharedApplication] delegate] window] rootViewController];
ViewController *view1 = [[ViewController alloc]initWithNibName:#"ViewController" bundle:nil];
[presentController presentViewController:view1 animated:YES completion:nil];

While creating the class make UIViewController its parent class.
It seems UIViewController is not the parent class of your class there is no .view of your object

You should present modal view controller in navigationController of rootViewController.
[self.window.rootViewController.navigationController presentModalViewController:res animated:NO];
So, if you really want to present modal view controller into rootViewController, remember:
If the window has an existing view hierarchy, the old views are removed before the new ones are installed.
Your first attempt to show modal viewController replace view hierarchy but self.window.rootViewController did not change and it is not in the window hierarchy anymore.
Or something like that.

Related

Master/Detail Project With Preceding View

I need to create a split view application that starts with basic view that I customize manually. Then I need to transition to the SplitView or push the master/detail table views onto the stack for the phone implementation.
The strategy I was planning to use would be placing the basic view into the detail pane on the SplitView controller, and while it was there just hide the side panel and button for the left pane in their respective orientations.
Is there a better way? Can I use a "plain" view as my root view, then switch it programmatically to a UISplitView?
For the phone version - this isn't really a problem. Since the navigation controller is the root view controller - I can just push more views onto the stack.
For the iPad - you cannot push a UISplitView controller onto the Navigation stack. I'd really like to do this so I have some concept of "back". I can create it programmatically - but before I do - I'd be interested in some other options if they exist.
I want to use Storyboards for this application - and the target version is iOS 5 - for ARC.
I've done this by replacing the root of the app. As first screen I had a LoginViewController, and when the login was successful, switched that ViewController with a UISplitViewController. You can do this animated too.
Edit:
Here is my code from the UIStoryboardSegue subclass:
- (void) perform
{
AppDelegate *appDelegate = (AppDelegate *)[UIApplication sharedApplication].delegate;
UIViewController *sourceViewController = (UIViewController *)self.sourceViewController;
UISplitViewController *destinationViewController = (UISplitViewController *)self.destinationViewController;
UIWindow *window = appDelegate.window;
window.rootViewController = destinationViewController;
window.rootViewController = sourceViewController;
[UIView transitionWithView:sourceViewController.view.window
duration:0.5
options:UIViewAnimationOptionTransitionFlipFromLeft
animations:^{
window.rootViewController = destinationViewController;
}
completion:^(BOOL finished){
}];
}
try this code:
you can add your LoginViewcontroller as A root view-controller in Delegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.viewController = [[LogInViewController alloc] initWithNibName:#"LogInViewController" bundle:nil];
self.window.rootViewController = self.viewController;
[self.window makeKeyAndVisible];
return YES;
}
and your loginButton Action:
-(IBAction)loginclick:(id)sender
{
objAppdelegate = (yourProjectnameDelegate *) [[UIApplication sharedApplication]delegate];
NSMutableArray *array = [NSMutableArray array];
HomeSpilitView = [[[UISplitViewController alloc] init]autorelease];
HomeMster = [[HomeSpilitViewController alloc] initWithNibName:#"HomeSpilitViewController" bundle:nil];
masterNavigationController = [[[UINavigationController alloc] initWithRootViewController:HomeMster] autorelease];
HomeMster.title=#"Title home";
masterNavigationController.navigationBar.tintColor =[UIColor colorWithRed:255/255.0 green:108/255.0 blue:61/255.0 alpha:0.1];
[array addObject:masterNavigationController];
HomeDetailsViewController *HomeDetailsViewControllers = [[HomeDetailsViewController alloc] initWithNibName:#"HomeDetailsViewController" bundle:nil];
detailNavigationController = [[[UINavigationController alloc] initWithRootViewController:HomeDetailsViewControllers] autorelease];
detailNavigationController.navigationBar.tintColor =[UIColor colorWithRed:255/255.0 green:108/255.0 blue:61/255.0 alpha:0.1];
HomeDetailsViewControllers.title=#"details title";
HomeMster.objHomeDetailsViewcontroller=HomeDetailsViewControllers;
HomeSpilitView.delegate = HomeDetailsViewControllers;
[array addObject:detailNavigationController];
[HomeSpilitView setViewControllers:array];
[objAppdelegate.window setRootViewController:HomeSpilitView];
}
//===for animation
UIInterfaceOrientation interfaceOrientation = HomeSpilitView.interfaceOrientation;
NSString *subtypeDirection;
if (interfaceOrientation == UIInterfaceOrientationLandscapeLeft) {
subtypeDirection = kCATransitionFromTop;
}
else if (interfaceOrientation == UIInterfaceOrientationLandscapeRight) {
subtypeDirection = kCATransitionFromBottom;
}
else {
subtypeDirection = kCATransitionFromRight;
}
[objAppdelegate.window setRootViewController:HomeSpilitView];
CATransition *animation = [CATransition animation];
[animation setDuration:0.5];
[animation setType:kCATransitionPush];
[animation setSubtype:subtypeDirection];
[animation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
[[objAppdelegate.window layer] addAnimation:animation forKey:#"SwitchToView1"];

UITabBarController Issue

I want to create something like below.
RootView does not have TabBar, From the second view there should be TabBar.
What I have currently done is, I am using UINavigationController as controller calass
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
UIViewController *rootController = [[ViewController alloc] initWithNibName:#"ViewController" bundle:nil];
navigationController = [[UINavigationController alloc] initWithRootViewController:rootController];
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
[self.window addSubview:navigationController.view];
[self.window makeKeyAndVisible];
return YES;
}
But how can I use UITabBar with tabBarController from SecondViewController?
create the objects of the second view and then push your view with the tabbarcontroller
From Storyboard embed your SecondViewController in TabBar. Select your controller and go to Editor -> Embed in -> TabBar Controller! I'm from my mobile..sorry if i have any mispells!
You need to push your Tabbar controller's object. Initialize your tab bar controller's object and add all other controller objects to the tabbar controller's viewcontroller array.
On button action:-
1> Initialize tab bar controller and suppose you name its object as objTab;
2> objTab.viewcontrollers = [NSArray arrayWithObjects:..] ---> Objects of all viewcontrollers that are a part of your tab bar controller. Thus all objects need to be created first.
3> self.navigationcontroller pushViewController: objTAb
Something like this should do the trick (not using ARC):
//vc1, vc2, vc3 = your view controllers
NSArray *viewControllersArray = [NSArray arrayWithObjects:vc1,vc2,vc3, nil];
UITabBarController *tabBarController = [[UITabBarController alloc] init];
[tabBarController setViewControllers:viewControllersArray];
[self.navigationController pushViewController:tabBarController animated:YES];
[tabBarController release];
What you want to do is create the UITabBarController and push that along the navigation stack.
For Sample Write loadnewview method at appdelegate .Use buttonPressed method for button action or any object action of first view controller as shown below to display tab bar from second view controller.
I have taken two tabs for sample so I wrote Capacity as 2. You can take up to 5.
-(IBAction)buttonPressed:(id)sender
{
HomeViewController *homeVC=[[HomeViewController alloc]initWithNibName:#"HomeViewController" bundle:nil];
[self.navigationController pushViewController:homeVC animated:YES];
[appDelegate loadnewview];
}
-(void)loadnewview
{
if(!self.tabBarController)
self.tabBarController = [[UITabBarController alloc] init];
self.tabBarController.delegate=self;
NSMutableArray *localcontrollerarray = [[NSMutableArray alloc] initWithCapacity:2];
UIViewController *viewController1 = [[HomeViewController alloc] initWithNibName:#"HomeViewController" bundle:nil];
UINavigationController *navi1 = [[UINavigationController alloc] initWithRootViewController:viewController1];
[localcontrollerarray addObject:navi1];
UIViewController *viewController2 = [[ScanViewController alloc] initWithNibName:#"ScanViewController" bundle:nil];
UINavigationController *navi2 = [[UINavigationController alloc] initWithRootViewController:viewController2];
[localcontrollerarray addObject:navi2];
self.tabBarController.viewControllers = localcontrollerarray;
[self.window addSubview:self.tabBarController.view];
}
use this type of method in AppDelegate.m and property-synthesize UITabBarController and store array of viewcontroller in it also in application didFinishLaunchingWithOptions method just assign navigationViewController as a RootViewController like bellow..
RootViewController *masterViewController = [[[RootViewController alloc] initWithNibName:#"RootViewController" bundle:nil] autorelease];
self.navigationController = [[[UINavigationController alloc] initWithRootViewController:masterViewController] autorelease];
after then when you want to add TabBar to any view at that time call this bellow method like this..
[appDelegate addTabBarControllerInwindow];
-(void)addTabBarControllerInwindow
{
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:1.0];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft forView:self.window cache:YES];
[self.navigationController.view removeFromSuperview];
[self.window addSubview:[tabBarController view]];//tabBarController.view
[UIView commitAnimations];
}
Create an Application using Tab Bar Controller and on the ViewDidLoad method of the view controller for which you want to hide the tab bar use code:
[self.tabBarController.tabBar setHidden:YES];
And don't forget to unhide the tab bar using the same code replacing NO instead of YES for the view controller for which you want to show the tab bar.

Unable to present modal view controller in didFinishWithResult

Is it possible to present Modal view controller in didFinishWithResult?
I have an iPad application with 3 views Home,Start and Login. Start and Login modal views can be launched using start and login buttons in home view.
If clicked on login button, after successful login operation (didFinishWithResult) in login view I am able to dismiss the login view and but i am not able to launch the start view. But the control stays back on home view.
I am not getting any error for the above scenario.
Appdeligate.m :
self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
HomeViewController * homeview=[[HomeViewController alloc] init];
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:homeview];
self.rootViewController = navigationController;
[navigationController setNavigationBarHidden:YES];
self.rootViewController.view.frame = [[UIScreen mainScreen] applicationFrame];
[self.window addSubview:self.rootViewController.view];
[window makeKeyAndVisible];
Below is the method in the home view which Present the login modal view
Presenting Login Modal View
LoginViewController * vc1 = [LoginViewController loginViewControllerWithNavBar:YES];
vc1.boxLoginDelegate = self;
[self presentModalViewController:vc1 animated:YES];
Note : LoginVeiwController is Modal view controller which is presented
by HomeViewController. Is it right way to launch/present another modal
view controller (start controller) by dismissing LoginVeiwController
as below. Because whenever the LoginVeiwController dismissed the control stays back on HomeVeiwContrller rather than launching/presenting StartViewController:
Home View :
Below is the method in the home view which will dismisses the login view on successful login and tries to launch the start view.
- (void)loginViewController:(LoginViewController *)loginViewController didFinishWithResult:(LoginResult)result {
[self dismissModalViewControllerAnimated:YES];
startview = [[[startViewController alloc] init] autorelease];
[self.navigationController setNavigationBarHidden:YES];
[self presentModalViewController:startview animated:YES];
}
If I present the StartView directly on button click, it launches nicely, but not on didFinishWithResult
Try like this. I think it will be helpful to you.
self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
HomeViewController * homeview=[[HomeViewController alloc] initWithNibName:#"HomeViewController" bundle:nil];
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:homeview];
[self.window addSubview:navigationController.view];
[window makeKeyAndVisible];
return YES:
you need to restructure this line in your code [self dismissModalViewControllerAnimated:YES]; the reason being when dismiss is called, you loose self context of the controller and hence the line [self presentModalViewController:startview animated:YES]; is not showing any controller further.
to quicktest just comment dismiss line and see for yourself.
use this line when your currentViewController DissMiss then try bellow code...
[self performSelector:#selector(PresentView) withObject:nil afterDelay:0.2];
-(void)PresentView
{
[self.navigationController presentModalViewController:startview animated:YES];
}
hope,this help you....
:)
I guess it's about the animation. While the previous controller is dismissing,
[self presentModalViewController:startview animated:YES];
is called.
You can verify my guess by setting the animation to NO. Or directly use my suggestion to see if it works.
If I am correct, you can set them back to YES.
Besides, instead of directly calling the
[self presentModalViewController:startview animated:YES];
You can try:
[NSTimer scheduledTimerWithTimeInterval:0.5f target:self selector:#selector(showController) userInfo:nil repeats:No];
- (void)showController {
[self presentModalViewController:startview animated:YES];
}
edit:
I finally found out how I solve this similar problem before:
- (void) imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
[UIView animateWithDuration:0.5
animations:^{
[self dismissModalViewControllerAnimated:YES];
}
completion:^(BOOL finished) {
NSURL *path = [info objectForKey:#"UIImagePickerControllerMediaURL"];
VideoConfirmViewController *videoConfirmCon = [[VideoConfirmViewController alloc]initWithFileURL:path];
[self presentModalViewController:videoConfirmCon animated:YES];
}
];
}
If you don't need compatibility with very old iOS versions it is better to use
-(void)presentViewControllerAnimated:completion:
-(void)dismissViewControllerAnimated:completion:
instead of
-(void)presentModalViewController:animated:
-(void)dismissModalViewController:animated:
In this case
- (void)loginViewController:(LoginViewController *)loginViewController didFinishWithResult:(LoginResult)result
{
[self dismissViewControllerAnimated:YES completion: ^{
startview = [[[startViewController alloc] init] autorelease];
[self.navigationController setNavigationBarHidden:YES];
[self.presentingViewController presentViewControllerAnimated:YES completion:NULL];
}];
}

Unable to navigate to next page iPhone

I am new to iPhone developer,
I have 4 page in my Application, my Application is viewBasedApplication.
I made my 1st page(LicAppViewController) as RootViewController, here is my code.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
self.viewController = [[[LicAppViewController alloc] initWithNibName:#"LicAppViewController" bundle:nil] autorelease];
UINavigationController *navigationController=[[UINavigationController alloc] initWithRootViewController:self.viewController];
[self.window addSubview:navigationController.view];
[self.window makeKeyAndVisible];
return YES;
}
on button click i am navigation to 2nd page(PlanPage)
-(void)btnClicked{
PlanPage *viewController = [[PlanPage alloc]initWithNibName:#"PlanPage" bundle:nil];
[UIView beginAnimations:#"Flip" context:nil];
[UIView setAnimationDuration:0.7];
[UIView setAnimationCurve:UIViewAnimationOptionCurveEaseInOut];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft forView:self.navigationController.view cache:NO];
[self.navigationController pushViewController:viewController animated:YES];
[UIView commitAnimations];
[viewController release];
}
till now it is working fine, but when i select a row in 2nd page it crashes my application, i want to navigate to 3rd page(DetailPlanPage), here is my code
DetailPlanPage *nextController = [[DetailPlanPage alloc] initWithNibName:#"DetailPlanPage" bundle:nil];
[self.navigationController presentModalViewController:nextController animated:TRUE];
but when i write, this line:
[self.navigationController pushViewController:nextController animated:YES];
instead of:
[self.navigationController presentModalViewController:nextController animated:TRUE];
it's working fine. (I am not sure but crash of my application may be because of viewBased Application)
Thanks In Advance !
set rootview controller first
remove that code
[self.window addSubview:navigationController.view];
and include
self.window.rootViewController = navigationController;
in present modal view controller u can try like this
yourview *detailViewController = [[yourview alloc] initWithNibName:#"yourview" bundle:nil];
UIBarButtonItem *doneButton = [[UIBarButtonItem alloc ] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:#selector(dismiss)];
detailViewController.navigationItem.leftBarButtonItem = doneButton;
UINavigationController *nav;
nav=[[[UINavigationController alloc] initWithRootViewController:detailViewController] autorelease];
[self presentModalViewController:nav animated:YES];
[detailViewController release];
[doneButton release];
-(void) dismiss
{
[self dismissModalViewControllerAnimated:YES];
}
Try
[self presentModalViewController:nextController animated:YES];
you would also want to set the delegate for nextController to self and add a delegate function to dismiss Modal View Controller.
The most important difference is about semantics. Modal view controllers typically indicate that the user has to provide some information or do something. This link explains it more in depth:
http://developer.apple.com/library/ios/#featuredarticles/ViewControllerPGforiPhoneOS/ModalViewControllers/ModalViewControllers.html
When you present a modal view controller, the system creates a parent-child relationship between the view controller that did the presenting and the view controller that was presented. Specifically, the view controller that did the presenting updates its modalViewController property to point to its presented (child) view controller. Similarly, the presented view controller updates its parentViewController property to point back to the view controller that presented it. And also another link.

navigate from one page to another in xcode

How can I navigate from one page to another page in xcode? remember without using the interface builder... I want the answer programmatically?
Pls be more precise if you want to get what you want.
If you are using view controllers within navigationcontroller you can make use of its pushViewController: or presentModalViewController:. Or if you just want to show another view you can just add the next view to existing view as subview.
Although your question is not much clear but still I would like to give a try...
You can use
UIViewController *yourViewController = [[YourViewControllerClass alloc] initWithNibName:#"<name of xib>" bundle:nil];
[self presentModalViewController:yourViewController animated:YES];
[yourViewController release];
In case the new view is also to be created programmatically, you can do that in the viewDidLoad method of YourViewControllerClass and change the initialization to
UIViewController *yourViewController = [[YourViewControllerClass alloc] init];
In YourViewController when you wish to come back to previous view on some button action you can use
[self dismissModalViewControllerAnimated:YES];
Another way that you can do is
UIViewController *yourViewController = [[YourViewControllerClass alloc] init];
[self addSubview:[yourViewController view]];
and to remove the view you can use
[self.view removeFromSuperview];
Hope this works for you, if yes please communicate....:)
//Appdelegate.m
-(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.viewController = [[ViewController alloc] initWithNibName:#"ViewController" bundle:nil];
UINavigationController *navigation = [[UINavigationController alloc]initWithRootViewController:self.viewController];
self.window.rootViewController = navigation;
[self.window makeKeyAndVisible];
return YES;
}
//In viewcontroller1.M
- (IBAction)GoToNext:(id)sender
{
ViewController2 *vc2 = [[ViewController2 alloc] init];
[self.navigationController pushViewController:vc2 animated:YES];
}