popviewcontroller is not calling viewWillappear - iphone

I'm using the following code to display the previous view when a user is clicking on a button
[self.navigationController popViewControllerAnimated:YES];
In the previous view, I overwrite viewWillAppear to initialized few things. However, it seems like viewWillAppear is not being called. I put NSLog in viewDidload, viewWillAppear, viewDidAppear and only viewDidAppear is being called. Is this normal behavior? If yes, what event should I override so I can do my initialization? Thank you.
As requested -viewWillAppear for the previous view
- (void)viewWillAppear:(BOOL)animated{
NSLog(#"ViewWillAppear");
//[[GameStore defaultStore] resetGame];
[self setHangmanImage];
NSLog([[[GameStore defaultStore] selectedList] label]);
[labelListName setText:[NSString stringWithFormat:#"List Name: %#", [[[GameStore defaultStore] selectedList] label]]];
[labelCurrentIndex setHidden:YES];
[labelCurrentWord setHidden:YES];
[[self navigationController] setNavigationBarHidden:NO];
[FlurryAnalytics logEvent:#"GameViewController - viewWillAppear"];
[self getNewQuestion];
NSLog(#"ViewWillAppear finish");
[super viewWillAppear:YES];
}
I setup the UINavigationalController in the app delegate using the following code
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
HomeViewController *hv = [[HomeViewController alloc] init];
UINavigationController *navController = [[UINavigationController alloc]
initWithRootViewController:hv];
// You can now release the itemsViewController here,
// UINavigationController will retain it
[hv release];
// Place navigation controller's view in the window hierarchy
[[self window] setRootViewController:navController];
[navController release];
// Override point for customization after application launch.
[self.window makeKeyAndVisible];
return YES;
}
UPDATE
I don't know what happened but last night after trying to run the app one more time in the simulator and its still having this issue, I decided to save everything and shut my computer down since it was getting late.
This morning I turned my computer back on opened up xcode, clean the project and build and run it and I the problem is fixed and -viewWillAppear is called. I didn't change anything and its working. I added NSLog in -willShowView and its not getting called. I don't know why all of a sudden viewWillAppear is being called.

Make sure your navigation controller's delegate is set and then use this function to call viewWillAppear in the class whose viewWillAppear you want to call:
- (void)navigationController:(UINavigationController *)navigationController
willShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
[self viewWillAppear:animated];
}

I've just hit a problem very much the same and after some testing discovered that calling popViewControllerAnimated: in a block (from a network response in AFNetworking) viewDidAppear isn't called in the parent view.
The solution that worked for me here was to call it in the main thread instead.
dispatch_async(dispatch_get_main_queue(), ^{
// If not called on the main thread then the UI doesn't invoke the parent view's viewDidAppear
[self.navigationController popViewControllerAnimated:YES];
});

I have just hit this problem as well the root cause of this problem is because I put self.navigationController.delegate = self on viewDidLoad. My solution is to put the delegation on viewWillAppear :
- (void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
self.navigationController.delegate = self;
}
After that popViewController will hit viewWillAppear.

Related

Why my presentModalViewController method doesn't work

I created a UIImagePickerController in the viewDidLoad method in my rootViewController.
- (void)viewDidLoad {
[super viewDidLoad];
UIImagePickerController *pickerController=[[UIImagePickerController alloc] init];
pickerController.sourceType=UIImagePickerControllerSourceTypeSavedPhotosAlbum;
pickerController.delegate=self;
[self presentModalViewController:pickerController animated:YES];
[pickerController release];
}
But the view of UIImagePickerViewController didn't appear on the screen.
The SDK version is 4.3
Is there some mistakes i make?
Thanks!
viewDidLoad is called after the view has been loaded and before the view is displayed. viewDidAppear: is called when the view is onscreen and is the correct point to present a modal view controller.
And if you want to do it only once, you might want to consider using a BOOL to keep track of it.

DismissmodalViewController donot remove the modal View

I have been figuring out this since yesterday but have not got that correct yet.
I have added the modalviewcontroller for my loading view controller on top of my tab bar controller and it works fine.
Added the code in app Delegate:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions: (NSDictionary *)launchOptions {
[navController.navigationBar setTintColor:[UIColor blackColor]];
[window addSubview:rootController.view];
[window makeKeyAndVisible];
LoadingViewController *lvc = [[LoadingViewController alloc] initWithNibName:#"LoadingView" bundle:nil];
// Delegate added here
lvc.loadingDelegate = self;
[rootController presentModalViewController:lvc animated:YES];
[self URL];
[lvc release];
return TRUE;
}
Now I do my parsing and when its done I call the following code in different view name XMLParsingView.m where the parsing got over.
- (void)handleLoadedApps
{
LoadingViewController *loading = [[[LoadingViewController alloc] init] autorelease];
//delegating to let the load view controller know to dimiss itself by defining disappear method in protocol
[loading.loadingDelegate disappear];
}
and in loading view controller I have method which calls dismissModalViewControlAnimated:
-(void)disappear{
[activity stopAnimating];
[activity removeFromSuperview];
[self removeFromSuperview];
[self dismissModalViewControllerAnimated:YES];
}
But for some reason it will never remove the view and not load it back to my tab bar controller.
Really need help here if any one have come across such issues.
Sagos
In your code you seem to create, without a nib, a new LoadingViewController and immediately go and dismiss it. In your app delegate you create your first loadingViewController with a nib, present it modally on rootController and then release it. Since you want to dismiss it outside your app delegate you have
3 choices, (hardest to fastest and most sane)
a) Key-Value-Observing on a property of XMLParsingView from LoadingViewController to remove itself when the task finishes.
b) Use delegation to inform the LoadingViewController when the task finishes to dismiss itself.
c) Fetch your rootController from your [[UIApplication sharedApplication] delegate], which means you must expose rootController as a property or through a method, and make rootController dismiss your modal.
You need to call dismissModalViewControllerAnimated on the rootViewController, not the loading view controller.

Navigation to another view in iphone

here is my code , i am trying to get from one view to another without any memory leaks.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
firstviewcontroller *first = [[firstviewcontroller alloc] init];
[window addSubview:first.view];
[self.window makeKeyAndVisible];
return YES;
}
-(IBAction)gotosecondview:(id)sender
{
secondviewcontroller *second = [[secondviewcontroller alloc] init];
[self.view addSubview:second.view];
[second release];
}
-(IBAction)gotofirstview:(id)sender
{
[self.view removeFromSuperview];
}
to make the above code work without crashing , all i have to do is remove [second release].
if I remove it I get memory errors (build and analyze) . how can i solve this problem. and i dont want to use [self.navigationController pushViewController:second animated:YES];
all i am trying to do i navigating from one view to another and vice versa WITHOUT using navigation controller. my firstviewcontroller and secondviewcontroller are of type UIViewController.
Thanks in advance.
You need to keep the current view controller alive while its view is showing (so it can process the user input, etc.).
In your code, you can achieve that in several ways:
Keep an instance of firstviewcontroller and secondviewcontroller as instance variables, and release them on the dealloc method.
Keep an instance variable with the currently in use UIViewController and release it when you switch to another view.
The code for the second option would look something like this:
#interface
UIViewController *currentViewController;
#end
#implementation
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions: (NSDictionary *)launchOptions {
firstviewcontroller *first = [[[firstviewcontroller alloc] init] autorelease];
[self switchToViewController:first];
[self.window makeKeyAndVisible];
return YES;
}
- (void)switchToViewController:(UIViewController *)aViewController {
[currentViewController.view removeFromSuperview];
[currentViewController release];
currentViewController = [aViewController retain];
[self.window addSubview:currentViewController.view];
}
-(IBAction)gotosecondview:(id)sender {
[self switchToViewController:[[[secondviewcontroller alloc] init] autorelease]];
}
#end
Here, all the logic for maintaining a single UIViewController alive lies in the switchToViewController method, which also handles the logic for switching from one view to another. As an added bonus, you can quickly add support for animations by adding a couple of lines in switchToViewController.
You can not release view in the call.
There is only one thing you can do in such conditions. use Autorelease,
The reason [second release] is crashing your code is likely because you're releasing your view controller which in turn releases the second view. The iPhone cookbook has some sample code on switching/swapping views if that's all that you're trying to accomplish. Here's the link. Hope this helps!
link text

Modal view controller returning

I have the following code where I display a view controller within a navigation controller.
Just for the test I display it for 3 seconds and then dismiss it.
What is happening is that it disappearing - and then reappearing after a second or so.
What am I doign wrong?
- (void) test
{
[myNavCtrl dismissModalViewControllerAnimated:YES];
}
- (void) viewDidAppear:(BOOL)animated
{
MyViewController *ctrl = [[MyViewController alloc] init];
[ctrl setDelegate:self];
myNavCtrl = [[UINavigationController alloc] initWithRootViewController:ctrl];
[myNavCtrl setModalTransitionStyle:UIModalTransitionStyleCrossDissolve];
[self presentModalViewController:myNavCtrl animated:NO];
[ctrl release];
[myNavCtrl release];
[self performSelector:#selector(test) withObject:nil afterDelay:3];
}
The viewWillAppear method is called every time the controller's view appears so you've created a loop. The view appears, it calls the modal view which covers the calling view. When the modal view disappears, the calling view controller's viewWillAppear gets called again. Lather, rinse, repeat.

Can presentModalViewController work at startup?

I'd like to use a modal UITableView at startup to ask users for password, etc. if they are not already configured. However, the command to call the uitableview doesn't seem to work inside viewDidLoad.
startup code:
- (void)viewDidLoad {
rootViewController = [[SettingsController alloc]
initWithStyle:UITableViewStyleGrouped];
navigationController = [[UINavigationController alloc]
initWithRootViewController:rootViewController];
// place where code doesn't work
//[self presentModalViewController:navigationController animated:YES];
}
However, the same code works fine when called later by a button:
- (IBAction)settingsPressed:(id)sender{
[self presentModalViewController:navigationController animated:YES];
}
Related question: how do I sense (at the upper level) when the UITableView has used the command to quit?
[self.parentViewController dismissModalViewControllerAnimated:YES];
You can place the presentModalViewController:animated: call elsewhere in code - it should work in the viewWillAppear method of the view controller, or in the applicationDidFinishLaunching method in the app delegate (this is where I place my on-launch modal controllers).
As for knowing when the view controller disappears, you can define a method on the parent view controller and override the implementation of dismissModalViewControllerAnimated on the child controller to call the method. Something like this:
// Parent view controller, of class ParentController
- (void)modalViewControllerWasDismissed {
NSLog(#"dismissed!");
}
// Modal (child) view controller
- (void)dismissModalViewControllerAnimated:(BOOL)animated {
ParentController *parent = (ParentController *)(self.parentViewController);
[parent modalViewControllerWasDismissed];
[super dismissModalViewControllerAnimated:animated];
}
I had quite the same problem. I know the topic is old but maybe my solution could help someone else...
You just have to move your modal definition in a method:
// ModalViewController initialization
- (void) presentStartUpModal
{
ModalStartupViewController *startUpModal = [[ModalStartupViewController alloc] initWithNibName:#"StartUpModalView" bundle:nil];
startUpModal.delegate = self;
[self presentModalViewController:startUpModal animated:YES];
[startUpModal release];
}
Next, in viewDidLoad, call your modal definition method in a performSelector:withObject:afterDelay: with 0 as delay value. Like this:
- (void)viewDidLoad
{
[super viewDidLoad];
//[self presentStartUpModal]; // <== This line don't seems to work but the next one is fine.
[self performSelector:#selector(presentStartUpModal) withObject:nil afterDelay:0.0];
}
I still don't understand why the 'standard' way doesn't work.
If you are going to do it like that then you are going to have to declare your own protocol to be able to tell when the UITableView dismissed the parentViewController, so you declare a protocol that has a method like
-(void)MyTableViewDidDismiss
then in your parent class you can implement this protocol and after you dismissModalView in tableView you can call MyTableViewDidDismiss on the delegate (whihc is the parent view controller).