If I run, within IOS not swift,
[[navigationController popViewControllerAnimated:YES] viewWillAppear:YES]
it calls viewWillAppear on the previous VC.
I need to jump back to the root VC and have that ViewWillAppear called; however,
[[navigationController popToRootViewControllerAnimated:YES] viewWillAppear:YES] gives me a coding error.
Is there a way to do this without applicationWillEnterForeground: and applicationDidBecomeActive: methods in my appDelegate
I have tried within init
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(willEnterForeground:)
name: UIApplicationWillEnterForegroundNotification
object:nil];
And in body
-(void) willEnterForeground:(Notification*)NotificationCenter
{
(self viewWillAppear:YES);
}
This doesn't seem to call viewWillAppear either.
Your code seems quite incorrect...
First, you should never call viewWillAppear - that is the system notifying your controller that the view will appear.
Second, just calling:
[self.navigationController popViewControllerAnimated:YES];
will navigate to the previous view controller in the stack, or:
[self.navigationController popToRootViewControllerAnimated:YES];
will navigate to the Root view controller.
In both cases, viewWillAppear is called by the system when the view, well, will appear.
Related
Scenario:
I need to show 3 or more popups one after the other on button click in each popup. I have created a different viewcontroller and xib files for each popup. So for displaying each popup I have used presentViewController instead of pushViewController.
That is, I have used this:
[self presentPopupViewController:searchPopUpView animationType:0];
instead of
[self.navigationController pushViewController:searchPopUpView animated:YES];
For dismissing a popup, the following code has been written:
[self dismissPopupViewControllerWithanimationType:0];
Issue:
The popups are displaying perfectly, but the background gets darker and darker whenever a popup shows up. After all popups have been dismissed I have to finally click on the blank screen to remove those darker parts. How to overcome this issue?
I think you are using MJPopupViewController to show pop-up.
If it is so, Then try this.
Suppose there is a controllerA from which you want to show a pop-up controller popupControllerB.
Then in your controllerA add Notifications Observer
Code to write in controllerA :
// Add Notification Observer when your view initialise.
[[NSNotificationCenter defaultCenter]addObserver:self selector:#selector(dismissPopup) name:#"DISMISS_POPUP" object:nil];
In viewWillDisappear remove the notifications observer
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
This method will be called when you Post-notification from your popupControllerB
-(void)dismissPopup {
[self dismissPopupViewControllerWithanimationType:MJPopupViewAnimationFade];
}
And In popupControllerB, Where you want to dismiss the Pop-up, write this code.
[[NSNotificationCenter defaultCenter] postNotificationName:#"DISMISS_POPUP" object:nil];
Above line of code will call a method written in your controllerA and dismiss the pop-up properly.
If you want to dismiss presented UIViewControllers you can use this code. I have used this approach to dismiss presentedViewControllers. It will dismiss all your presentedViewControllers on your rootViewController.
UIViewController* presVC = self.window.rootViewController;
while (presVC) {
UIViewController* temp = vc.presentingViewController;
if (!temp.presentedViewController) {
[vc dismissViewControllerAnimated:NO completion:^{}];
break;
}
vc = temp;
}
I need to go back all the way to the view controller that presented the first navigation controller. However I haven't dismissed multiple controllers before at once, and when I've tried doing so, it doesn't work. It just goes to the first navigation controller instead of all the way to the one before it.
Here is my current code:
[(UINavigationController *)self.presentingViewController popViewControllerAnimated:NO];
[self dismissViewControllerAnimated:YES completion:nil];
I have a view controller which modally presents the first navigation controller. The first navigation controller screen is called Main View Controller. It then pushes to Login View Controller. Login View Controller does presentViewController to MenuViewController (UIViewController).
I need to get from MenuViewController all the way back to the view that presented the first navigation controller. Thanks.
Try this
UIViewController *vc = self;
while (vc.presentingViewController != nil) {
vc = vc.presentingViewController;
}
[vc dismissViewControllerAnimated:YES completion:nil];
One option would be to use NSNotifications.
You can add an observer in your first/root/initial UINavigationController subclass e.g.
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(logout:)
name:#"LogoutNotification"
object:nil];
Then in your "logout:" method you have direct control over the initial UINavigationController rather than those further up the hierarchy.
You can then send an NSNotification from anywhere in the app in order to trigger the method.
e.g.
[[NSNotificationCenter defaultCenter] postNotificationName:#"LogoutNotification" object:self];
My application handles opening email attachments. To do this in my AppDelegate I call my dedicated ViewController which is the RootViewController of my App thanks to popToRootViewControllerAnimated:.
I do some treatments in viewWillAppear and viewDidAppear of RootViewController but they are not called if the view controller that was displayed before switching to the mail application was my RootViewController!
Case 1 : Usual viewWillAppear / viewDidAppear methods aren't called :
(RootViewController -> switch to Mail App -> Open attachement in my app -> in AppDelegate popToRootViewControllerAnimated -> RootViewController)
Case 2 : Usual viewWillAppear / viewDidAppear methods are called :
(OtherViewController -> switch to Mail App -> Open attachement in my app -> in AppDelegate popToRootViewControllerAnimated -> RootViewController)
Found on the internet this trick but it doesn't work in case 1: http://www.idev101.com/code/User_Interface/UINavigationController/viewWillAppear.html
How can I fix this and call usual viewWillAppear / viewDidAppear methods all the time?
Your view controller is already visible so it's normal that viewWillAppear doesn't get called.
If you want to know when the user gets back to your app just add the following code in RootViewController init method :
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(willEnterForeground:)
name: UIApplicationWillEnterForegroundNotification
object:nil];
and implement what you want in
- (void)willEnterForeground:(NSNotification *)notification
Don't forget to stop observing on when RootViewController will be deallocated :
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
Sounds like it is because in Case 1, within the context of your app your RootViewController is already 'visible' and therefor popToRootViewController doesn't have to do anything.
viewWillAppear: and viewDidAppear: methods are called only when such a thing happens relative to your application. These methods are not called when you switch between applications. You should depend on the applicationWillEnterForeground: and applicationDidBecomeActive: methods in your appDelegate.
One more thing to note is that when you are doing
RootViewController -> popToRootViewControllerAnimated -> RootViewController
Your root view controller's view is already visible and thus it will not fire the viewWillAppear: and viewDidAppear: methods.
I recommend you do something similar to this
RootViewController.m
-(void)viewDidAppear:(BOOL)animated
{
[self doSomething];
}
-(void)doSomething
{
//Your functionality
}
AppDelegate.m
- (void)applicationDidBecomeActive:(UIApplication *)application
{
[self.window.rootViewController doSomething];
}
You can also add your root view controller as a listener to the UIApplicationDidBecomeActiveNotification or UIApplicationWillEnterForegroundNotification
I have 2 viewcontrollers with segue "page curl"
viewcontrollerA => pagecurl => viewcontrollerB
and Now I want to update viewcontrollerA since user make some change at viewcontrollerB.
I tryed:
UIStoryboard* sb = [UIStoryboard storyboardWithName:#"mystoryboard"
bundle:nil];
UIViewController* vc = [sb instantiateViewControllerWithIdentifier:#"ExampleViewController"];
[vc ViewDidLoad]; // or ViewWillAppear or ViewDidApear
it works only for the NSLog I put in those functions.
but none of them works with the function which check out Coredata and update the interface.
please help
try this code:
you add parent class
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(actionremovecalender:)
name:#"subMitReport"
object:nil];
-(void)actionremovecalender:(NSNotification *)notification
{
[self ViewDidLoad]
}
call child class
[[NSNotificationCenter defaultCenter]postNotificationName:#"subMitReport" object:nil]
You can send a NSNotification that the parent will receive, or you can set a delegate with a method implemented by the parent view.
In both cases, just reload the view.
In a one-to-one relation, you should prefer the delegation pattern. Just add a weak reference of viewcontrollerA to your viewcontrollerB. You can just call a method (in this case viewDidLoad method) of viewcontrollerA using the reference so you can refresh the views. But I'd prefer declaring a protocol for delegation to prevent tight coupling of two view controllers.
ViewWillApear or ViewDidApear will be called since there is any object changes in the viewcontroller, but if you want to change your viewcontrollerA from another viewcontrollerB, that require NSNotificationCenter to call the function from viewcontrollerA
you can always use NSNotificationCenter to update your parent viewcontroller
At your parent viewcontroller put this:
//since child view controller calls turnItOff, notification center calls function "turnButtonCountinuesOff"
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(turnButtonCountinuesOff) name:#"turnItOff" object:nil];
turnButtonCountinuesOff is your function at parent viewcontroller
At your child viewcontroller put this:
//connect to parent UI view controller calls notification turnItOff.
[[NSNotificationCenter defaultCenter] postNotificationName:#"turnItOff" object:nil];
hope it helps.
I have 2 view controllers, vc1 and vc2. A modal segue is invoked from vc1 when I want to load vc2. Say I background the app when vc2 is showing. Why isn't viewDidAppear called when the app is re-opened to the view that was left off? How else am I able to detect every time vc2 appears?
You could register for the UIApplicationDidBecomeActiveNotification in VC2 and call viewDidAppear from there. Do this in your viewDidLoad of VC2:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(somethingThatWillCallViewDidAppear:)
name:UIApplicationDidBecomeActiveNotification
object:nil];
As rmaddy says below, make sure to remove the observer in dealloc or viewDidUnload.