it happens only on the 3GS, 4 or 3G is OK.
seems like viewcontroller got called everytime camera dismissed.
any thoughts on that?
It's Iphone, the system calls viewdidunload my view of viewcontroller when I did a
[self presentModalViewController:picker1 animated:YES];
I don't want the system to dismiss my view. I did a [self.view retain] but that doesn't help.
viewDidLoad can be called multiple times. If the iPhone needs memory, it will release the view and then rebuild it the next time it has to show it. This is normal -- you cannot count on only a single call. You should get a viewDidUnload call before it's called again.
Related
I'm running all my apps to make sure it's not just one app, and in every app I have, when I run on the iOS5 simulator or device, the viewWillAppear method gets called twice on every view. I have a simple NSLog(#"1");, and this appears twice in my console every time. Is this just me, or is something going on? (It only gets called once in iOS4)
This is the code calling the view that calls viewWillAppear twice:
CloseDoorViewController *closeVC;
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
closeVC = [[ CloseDoorViewController alloc] initWithNibName:#"CloseDoorViewIpad" bundle:nil];
} else {
closeVC = [[ CloseDoorViewController alloc] initWithNibName:#"CloseDoorViewController" bundle:nil];
}
[self.view addSubview:closeVC.view];
[self presentModalViewController:closeVC animated:NO];
It's the -addSubview: method.
When adding or removing view controller's view, someone must call 'View Event' methods such as -viewWillAppear:, etc. of the view controller.
Actually, it wasn't a recommended way to -addSubview:/-removeFromSuperView view controller's view by yourself before iOS 5, because it doesn't call 'View Event' methods (you can/should call it by yourself). Instead, it was recommended to use 'indirect' way to do that, such as -presentModalViewController: you use (it does call 'View Event' methods on your behalf).
On iOS 5, Apple has changed the behavior of -addSubview:/-removeFromSuperView methods to allow direct view management of view controller. So now, when you use those methods on viewController's view, 'View Event' methods will be called automatically.
So it was called twice.
See video "Implementing UIViewController Containment" on here also.
Because you are displaying the view twice.
First time by adding the view as a subview of the current view:
[self.view addSubview:closeVC.view];
Second time by pushing the view's controller on top of current view's controller:
[self presentModalViewController:closeVC animated:NO];
I'm not sure why in iOS4 the viewWillAppear was only called once, because iOS5 is correct to call it twice, given that you are displaying the view twice as explained above.
Just remove one of the lines and it would be fine (I'd recommend removing the addSubview and retain the presentModalViewController one).
If you want to restore the old (iOS 4) behavior in your view controller you should implement the following method:
- (BOOL)automaticallyForwardAppearanceAndRotationMethodsToChildViewControllers {
return NO;
}
Update: since you have edited your question to include a code sample, it is clear what the problem is. Lukman's answer above is correct/excellent.
Original answer before code was included:
I would try putting a breakpoint (or log statement) in the -init method of this class. If that is hit twice, then two view controllers are being created.
(note if you have not already overridden the -init method in this class, make sure you override the designated initializer which is -[UIViewController initWithNibName:bundle:])
http://developer.apple.com/library/ios/#DOCUMENTATION/UIKit/Reference/UIViewController_Class/Reference/Reference.html
.
Hi, everyone.
I have a custom ViewController(1) and presented another ViewController(2) modally.
While Modal ViewController(2) is showing, it received memory warning and changed orientation.
After then, I dismissed Modal ViewController(2).
And I checked the sequence of call back function on ViewController(1).
willRotateToInterfaceOrientation
loadView
viewDidLoad
willAnimateRotationToInterfaceOrientation
didRotateFromInterfaceOrientation
...
is it normal to be called willRotateToInterfaceOrientation function before loadView?
Is it normal? What does that matter? If your results are correct, willRotateToInterfaceOrientation is called first.
This is not a huge deal, however: if you need to access the view inside willRotateToInterfaceOrientation, just make sure to access [self view] or self.view in your code. If the view isn't already loaded, it will be loaded right then, calling loadView and viewDidLoad as necessary before returning control back to willRotateToInterfaceOrientation.
If you have outlets set up that are connected when the view loads (probable), just insert [self view]; at the top of the method to force the view to load and the outlets will be connected when it returns. Then you can call self.bigButton.enabled = NO; or whatever else you'd like to do.
I will like my application that always starts as the first time I open it. I have several view controllers and when I exit my application and I open it again I see the view controller where I left of. Maybe I have to call the method applicationWillTerminate method.
I use this code to open a new view:
UIViewController *control = [[SomeViewController alloc] initWithNibName:#"SomeViewController"
bundle:nil];
UINavigationController *navControl = [[UINavigationController alloc]
initWithRootViewController:control];
[self presentModalViewController:navControl animated:NO];
[navControl setNavigationBarHidden:YES];
[control release];
[navControl release];
this code works great when linking it to buttons. But when I place that code in the applicationDidBecomeActive method it does not work.
The easiest way is to set UIApplicationExitsOnSuspend in Info.plist.
That really isn't the expected behaviour, though. Users expect to see the app "where they left off", especially if they've only briefly left the app (e.g. because they got a phone call).
Your code snippet adds a view controller, but is unlikely to work since your app delegate is not a UIViewController. It also doesn't do anything about removing the old view controllers.
EDIT: If all you need to do is display a splash screen (or something), then it's something like this:
In -applicationDidEnterBackground:, add a "splash screen" view (not a view controller) to self.window. (iOS takes a "screenshot" after you return from -applicationDidEnterBackground: and uses this in the app-switch animation; you want this to be what the user sees when switching back to your app)
In -applicationWillEnterForeground:, do whatever animations you want and eventually remove the view from the window (call -removeFromSuperview).
EDIT 2: The same will work in -applicationWillResignActive:/-applicationWillBecomeActive:, except this happens on a sleep/wake event, which might not be what you want...
I'd avoid using view controllers for this, because trying to shoehorn a view controller in the view controller hierarchy is likely to be problematic (for example, you have to figure out which VC to present it from, and you have to do the "right thing" if the user backgrounds your app while the VC is on screen, and...)
The reason it doesn't work in applicationDidBecomeActive is that method is only sent to the Application delegate, which doesn't know about presentModalViewController.
I suggest instead that in your appDelegate, implement applicationWillEnterForeground:, which should restore the state to a newly launched application (equivalent to what the state is at the end of application:didFinishLaunchingWithOptions: ).
OR...(edits)
If you just want a certain viewController to run (which is still loaded, right?)...For example, if you have a tab controller and just want to go to the root of the first view controller, put the following code into applicationWillEnterForeground:
UITabBarController * myTabBar = self.tabBarController;
myTabBar.selectedIndex = 0;
[[myTabBar.viewControllers objectAtIndex:0] popToRootViewControllerAnimated:NO];
Temporary solution:
I made my application crash on applicationWillResignActive method and it works. My application needs to run an animation when I launch it. But this works because next time the application runs it starts like the first time I opened it.
my question is that i use ios 4.1 and viewWillAppear is not call when i go via
[self.view addSubView:self.mySecondView.view];
then and in the first view i alloc second view on ViewDidLoad .. i just want to call ViewWillApear on Second View because want to do the task dynamic.
is their some thing alternative... because InitWithNibName method also fire when alloc and init occur.. i want to fire some method when i add to that view.
Thanks
The same issue is discussed before,Just go through below SO links.
iPhone viewWillAppear not firing
viewDidLoad gets called, viewWillAppear does not get called, view does not appear on screen
http://forums.macrumors.com/showthread.php?t=575530
here is the tutorial post
http://www.idev101.com/code/User_Interface/UINavigationController/viewWillAppear.html
I have an app that starts with a tableview (from a xib) that loads multiple navigation controllers. I want to present a modal view on startup if a long init sequence is underway. I tried presenting a modal view in the App Delegate, but the view doesn't appear until well after the underlying code is already complete.
MainWindow.xib loads TableViewController, so I put my call to presentmodalview in that View Will Appear with the same result. I have numerous NSLOG calls so I can watch what is happening but I can't figure out why the view doesn't appear until after both the app delegate and the tableview controller's viewWillAppear finish. I moved the call to viewDidAppear with the same result. Here is a code snippet:
App Delegate:
- (void)applicationDidFinishLaunching:(UIApplication *)application {
// Add the tab bar controller's current view as a subview of the window
[window addSubview:tabBarController.view];
[window makeKeyAndVisible];
[[UIApplication sharedApplication] setStatusBarHidden:NO];
// if new version being installed do init stuff
if ( <needs update code here>) {
Uncompress *uncompressView = [[Uncompress alloc] initWithNibName:#"Uncompress" bundle:nil];
[self.tabBarController presentModalViewController:uncompressView animated:NO];
[uncompressView release];
}
}
I also tried changing presentmodalviewcontroller to [window addSubview:uncompressView.view] without any luck.
The Update code runs just fine, the problem is the view doesn't appear until both the AppDelegate and the TableView are finished. I'm not creating any views programatically - all are from Xib's. I can't figure out where to call the update function to get the view to appear right away. Any help appreciated. Thank you!
On iOS, the UI is only updated when your code returns control to the run loop. So if your uncompress task takes a lot of time, the UI will only be updated after it has finished.
You can sort of work around this issue by putting the time-intensive task in a separate method and calling that method with [self performSelector:... afterDelay:0.0 ...]; but it is not a good solution because even if the UI will update, user interaction with your app will still be blocked as long as your code blocks the main thread. And if your code takes more than a few seconds to run (e.g. because it runs on an older, slower device), the OS watchdog timer will kill your app.
The best solution would be to put the time-intensive task in a background thread, e.g. with NSOperation or dispatch_async().