I have a programmatically created UIViewController named as "VC" and on top of that I need to load my existing UIViewController.
I used below code to do that, and it's working fine.
I can see my existing UIViewController on "VC" but not detecting any of viewDidAppear or viewWillAppear in existing view controller.
I am getting data from viewDidAppear and viewWillAppear so all the time my existing view controller collection view is empty.
ExistingViewController* presObj= [self.storyboard instantiateViewControllerWithIdentifier:#"oad"];
[vc.view addSubview:presObj.view];
[self addChildViewController:presObj];
[presObj didMoveToParentViewController:self];
Have you initialize the storyboard class?
self.storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
so all the time my existing ViewController collection view is empty --> are you using collection view in your code?
First you need to add the addChildViewController. Then add that childviewcontroller view into your main view.
Just add the [self addChildViewController:presObj]; before adding to the view subview.
ExistingViewController* presObj= [self.storyboard instantiateViewControllerWithIdentifier:#"oad"];
[self addChildViewController:presObj];
[vc.view addSubview:presObj.view];
[presObj didMoveToParentViewController:self];
Ok, If you are loading like this then your ViewDidLoad () of existing view controller will load, and you can put a condition (if needed) then you can call ViewDidAppear () ViewWillAppear() like below
existingviewcontroller *obj=[[existingviewcontroller alloc]init];
[obj viewWillAppear:YES];
[obj viewDidAppear:YES];
This will work
Related
I have multiple UIViewController objects within one main UIViewController. I need to call FVC method when I click the main view controller button. Here three view controllers having three separate class files.
From your first controller on didSelectRowAtIndexpath method,
UIStoryboard * board = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
ViewController * cntrl = [board instantiateViewControllerWithIdentifier:#"ViewController"];
[self presentViewController:cntrl animated:YES completion:^{
}];
add above code. Here ViewController is nothing but a your Second view controller. Using reference of cntrl pass data to Second controller.
When you want to navigate to any other controller without having navigation controller reference , you use present view controller.
If you are trying to call a method present in other ViewController without presenting it, I guess you are doing it wrong, because that method belongs that ViewController class and ideally should be called when that ViewController's lifecycle is in progress.
For your scenario, I suggest that you should create a utility class, move that method which accepts two strings and then processes something in that utility class and then call that method from your ViewController1 something like :
[UtilityClassName yourMethodWithFirstString : str1 andSecondString : str2];
Hope that clears.
UIViewController *viewVC = [[UIViewController alloc] init];
[self presentViewController:viewVC animated:YES completion:nil];
//Loading a view controller from the storyboard
UIViewController *viewVC = [self.storyboard instantiateViewControllerWithIdentifier:#"IDENTIFIER_OF_YOUR_VIEWCONTROLLER"];
[self presentViewController:viewVC animated:YES completion:nil];
In First View Controller
//Do this inside your btnCall method
SecondViewController * cntrl = [self.storyboard instantiateViewControllerWithIdentifier:#"secondViewControllerIdentifier"];
[cntrl methodName:firstParameter:secondParameter];
In SecondViewController
In .h file
-(void)methodName:firstParameter:secondParameter;
In .m file
-(void)methodName:firstParameter:secondParameter{
//Do your task here
}
Hi i have been working on an iOS app.What i am doing is navigating among diffrent view controllers. But the problem is i want finish the current view controller from emoery and then move to the next view controller.
I am using `[self.view removeFromSuperview]; for finishing the cureent view & using
self.loginView = [self.storyboard instantiateViewControllerWithIdentifier:#"LOGIN"];
[self presentViewController:self.loginView animated:NO completion:nil];
for moving to next view controller but the thing is i am not able to remove it from memory.
Please tell me how can i do it?
Thanks in advance.
`
It's better to create a container view controller which manages your view controllers. For example, in viewDidLoad: of container controller you add current controller:
[self addChildViewController:self.currentViewController];
[self.currentViewController didMoveToParentViewController:self];
[self.view addSubView:self.currentViewController.view];
//here set up currentViewController view's frame or constraints if needed
When you need to open login controller, do this:
[self addChildViewController:loginViewController];
[self.loginViewController didMoveToParentViewController:self];
[self.view addSubView:loginViewController.view];
//here set up loginViewController view's frame or constraints if needed
//then remove current view controller
[self.currentViewController willMoveToParentViewController:nil];
[self.currentViewController removeFromParentViewController];
[self.currentViewController.view removeFromSuperview];
Remove from superview will remove it from the current view, but OS won't remove it until he needs to (this is topic for more explanation, let's say it won't remove it asap).
If you want something deleted just call it nil:
self.view = nil;
This will make the pointer to nil, so view won't be there any more. (the view really will be somewhere but you won't have access to it)
I am revising your code
self.loginView = [self.storyboard instantiateViewControllerWithIdentifier:#"LOGIN"];
[self presentViewController:self.loginView animated:NO completion:nil];
What you are doing here is presenting your login viewcontroller.
self: This is the instance of the viewcontroller you are currently working on. So how could you remove self from memory. (Not Possible)
You can approach alternate ways.
For example: 1. Changing root view controller
Pop to root view controller and then Push Login View controller.
If you try to remove not only UIView but the whole UIViewController from a navigation controller stack use this snippet
NSMutableArray *stack = [[NSMutableArray alloc] initWithArray: self.navigationController.viewControllers];
[stack removeObject:yourController];
self.navigationController.viewControllers = stack;
Be aware of using this only when you've already pass to the next controller view.
UPD:
Oh, now I see what you are trying to do. And I can't figure out, why you're trying to step your controllers this way (modally). I think you should use UINavigationController with navigation segues defined directly from your storyboard. Look at this article where apple purely explains what navigation is. That article is about modal views
on viewdidload of one of my tabbar viewcontrollers I'll like to display or popup another view controller. here's my code
if (_history.count == 0) {
//[self performSegueWithIdentifier:#"emptyHistorySegue" sender:self];
UIStoryboard* sb = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
MSAEmptyHistoryViewController *popupController = [sb instantiateViewControllerWithIdentifier:#"EmptyHistoryViewController"];
[self presentViewController:popupController animated:NO completion:nil];
}
The load the viewcontroller on top of the tabview controller. I need this view to display but still allow the user to see the tabbar buttons.
You will run into problems if you try to transition to another view controller in viewDidLoad. You should either switch the child view controllers of the tab bar controller or you can present a subview within one of the child view controllers.
When -viewDidLoad is called, the view controller is generally not presented. As such, if you try to present another controller, it will crash.
Try -viewDidAppear: if you want what you are describing.
I have tab bar based application (iOS 7.1 SDK). When user start app at first time, I want show some login screen. I decided to use view controller containment (this is called in first view controller of tab bar controller):
LoginViewController *vc = [LoginViewController new];
[self.tabBarController addChildViewController:vc];
[vc didMoveToParentViewController:self.tabBarController];
[self.tabBarController.view addSubview:vc.view];
But there are some problems. View is normally visible, but in LoginViewController viewWillAppear and viewDidAppear are never called. I try to use this piece of code in all view lifecycle methods (viewDidLoad, viewWillAppear, viewDidAppear), but with no luck. I know there are some other ways to achieve what i'm trying to do. For example add child controller to first view controller of tab bar controller and hide tab bar, which works great and viewWillAppear and viewDidAppear are normally called. But because of this I get even more curious - why adding child view controller to tab bar controller don't work as expected?
You need to present or push the viewcontroller in order for the methods to get called. Just adding the view as a subview will not work.
In your case, you can explicitly call the viewWillAppear, viewDidAppear methods.
LoginViewController *vc = [LoginViewController new];
[self.tabBarController addChildViewController:vc];
[vc didMoveToParentViewController:self.tabBarController];
[self.tabBarController.view addSubview:vc.view];
[vc viewWillAppear];
[vc viewDidAppear];
It's working!
dispatch_async(dispatch_get_main_queue(), ^{
[self.tabBarController setSelectedIndex:0];
[self.tabBarController setSelectedIndex:1];
[self.tabBarController setSelectedIndex:0];
});
I am having major memory management issues. After small use of the program it will crash running out of memory. I have finally found the cause, every time I create a new ViewController rather than accessing the instance, I am creating a new instance.
So app loads and instantiates the FirstViewController. You click a button which instantiates FilterViewController. From here when going back to FirstViewController I am creating a new instance of this as follows:
UIStoryboard *storyboard = [UIStoryboard storyboardWithName
:#"MainStoryboard" bundle:nil];
FirstViewController *fvc = [storyboard
instantiateViewControllerWithIdentifier:#"FirstViewController"];
fvc.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
And repeat process. Any way of presenting the view controller without re-instantiating it? I am close to submitting the app (tomorrow hopefully) so I need to try get this sorted. Thanks!
Here is the presentation of the ViewController.
[self presentViewController:fvc animated:YES completion:nil];
Presenting FilterViewController from FirstViewController
- (IBAction)searchOptions:(id)sender {
FilterViewController *ctrl = [[FilterViewController alloc] init];
[UIView transitionFromView:self.view toView:ctrl.view duration:1 options:UIViewAnimationOptionTransitionCurlUp completion:nil];
self.filterViewController = ctrl;
[self.navigationController pushViewController:self.filterViewController animated:NO];
}
If you're using presentViewController, you get back to the previous view by calling [self dismissViewControllerAnimated:YES];. You would do that in the method where you're currently creating the new controller.
If you are pushing into a navigation controller you would pop from the navigation controller: [self.navigationController popViewControllerAnimated:YES];.
Based on your last update it seems like you don't have a navigation controller and you're just adding the view as a subview and storing the filter view controller. That makes life more complicated really and the correct way to remove it is to setup a delegate relationship so that the filter view controller calls back to the first view controller when it's done and the first controller then transitions the views and nil's the reference.
If you can, change to use a navigation controller properly. You already have half the code, but the first view controller seems to not be in a navigation controller. If you use a nav controller life will be easy...