I used many properties as Textfield, labels, Textviews, Uiviews, Tableview, scrollview in employer_REG_NEW Viewcontroller. Now when I call push viewcontroller it takes upto 3 seconds to load the new viewcontroller
My code is
employer_REG_NEW *empSIGHN_UPVC = [[employer_REG_NEW alloc] initWithNibName:#"employer_REG_NEW" bundle:nil];
[[self navigationController] pushViewController:empSIGHN_UPVC animated:NO];
Make sure that you are not doing any heavy processing in
viewDidLoad: , viewWillAppear: and viewDidAppear: methods which may overload the main thread.
Related
This is how am pushing from ViewController A to ViewController B
UIStoryboard *mainStory = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
ListingViewController *listView = [mainStory instantiateViewControllerWithIdentifier:#"listing"];
[self.navigationController pushViewController:listView animated:YES];
and i've tried this way as well using a segue in StoryBoard
[self performSegueWithIdentifier:#"Associate3" sender:sender];
Pushing to this ViewController for the first time freezes (around 4 sec) before start pushing, knowing that VC B contains UIScrollView Object in its XIB,
Did this happened to any of you, any one knows how to solve this delay?
EDIT:
i've already commented all webservice calling methods, nothing Changed! I think its an allocating delay, am using the storyboard initiating with identifier to push VC B, but when i used allocating method: VC *B = [[VC alloc] init], then pushing to this view works without delay, but the issue that i don't need to use the allocating method!!
Finally found the issue, it was the custom font that am using in the labels of the VC B, just set them back to System Font instead of Roboto solved my problem, i think the system takes time to find the Font with specific name. Hope this would be useful for others
It seems you are performing some heavy operation on main thread in ViewWillAppear or ViewDidLoad of ViewController B
Comment whole code of both above mentioned methods and then run your application which verifies problem in app.
So if its verified then you must move your heavy operation from main thread to background thread.
This might be because pushing is executed in different thread. Try pushing the viewController in main thread. i.e.,replace your push controller code with
dispatch_async(dispatch_get_main_queue(), ^{
UIStoryboard *mainStory = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
ListingViewController *listView = [mainStory instantiateViewControllerWithIdentifier:#"listing"];
[self.navigationController pushViewController:listView animated:YES];
});
Try to change in ListingViewController class viewDidLoad method to call async
- (void)viewDidLoad {
[super viewDidLoad];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
//move your code here
// if you need to do something on ui (reload table view e.t.c) - call async in main thread
dispatch_async(dispatch_get_main_queue(), ^{
//Your UI code
});
});
}
You can use 'Instruments-Time Profiler', a developer tool with Xcode. It can check the time expense. Then, I think you will find you problem.
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
1) I have two controllers, fistViewController, secondViewController.
2) first controller implements the delegate say "xyzDelegate".
#interface FirstViewController : UIViewController <xyzDelegate>
3) The delegate method in First View Controller refreshes the UIViewTable.
4) First Controller : Pushing Second View Controller.
SecondviewController *svc = [[SecondViewController alloc] initWithNibName:#"SecondViewController" bundle:nil];
svc.delegate = self;
[self.navigationController pushViewController:svc animated:YES];
4) In second View Controller:
id<xyzDelegate> strongDelegate = self.delegate;
[self.navigationController popViewControllerAnimated:YES];
NSLog (#"After popViewControler");
[strongDelegate dateSelected:dateChoosen]; // Invoking Delegate Method.
Question:
1) Is it the general practice to invoke the delegate method after Popping View Controller?
as i am refreshing the UITable, once the delegate method is invoked in FirstView Controller.
Usually, a view controller is an independent unit of screens. Especially if it's switched by navigation-controller. You are expected to reconfigure views to bind their data in one of overriding of viewWillAppear: or viewDidAppear: method.
Usually viewDidAppear: is preferred. Because in many cases, switching view needs reloading of underlying data, and this usually causes asynchronous I/O. In this case, this asynchronous I/O may interfere simultaneously performing view-switching animation.
Anyway, if your view setup operation is lightweight, it's fine and better to go with viewWillAppear: because it will make your user to wait less.
In this case, IMO, it seems your best bet is just marking to refresh the data on the target view controller, and handle refreshing in the view-controller's viewDidAppear: method.
You should call the delegate methods BEFORE POP action occurs.
[strongDelegate dateSelected:dateChoosen];
popViewControllerAnimated Will call second view controller dealloc method to destroy, where you would release the strongDelegate. So no more strongDelegate to receive the dateSelected: method.
[self.navigationController popViewControllerAnimated:YES];
I have this view controller (class1) , which has a UICollectionView in it .
When i am finish with this view, i am going to the next view, but i can see that the memory consumption of this view(class1) is not cleared and being added to the next view (class2).
Both view controllers are made with storyboard, and has a name , and when i finish with view1 (class1) i am going to the next one with :
//in view1 i do when exit
UIViewController *mainV=[self.storyboard instantiateViewControllerWithIdentifier:#"MainView"];
mainV.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
[self presentViewController:mainV animated:YES completion:^(void)
{
[self.myCache removeAllObjects];//NSCache
[self.GridView removeFromSuperview]; //collection view
[self.view removeFromSuperview];
}];
Seems that memory is still not freed.
Is there another way to move to next view and just clear everything before ?
In that code class1 is presenting class2. But class1 is still there, presenting class2, until it does a "dismissViewController:" method.
If you want to go back to mainView from class1. And in the case of class1 being presented by mainView. Then mainView have to do a dismissViewController:
In other case you are stacking a pile of view controllers, one presenting the next one.
The pattern most used in objetive-c is to send a message from class1 to its presenter. A delegation pattern. The presenter then dismiss the viewController.
Even after grid view is removed from superview, it won't be cleared from memory if it's an iVar of your view controller class or a strong property. Try setting GridView to nil after you call [self.GridView removeFromSuperview].
I have run into a strange issue where pushing a custom UIViewController is resulting in a long delay before my controller appears. If I change my code to present the controller instead of pushing it there is no delay.
I am not doing anything fancy when I create and push my VC:
MyCustomViewController *myView = [[MyCustomViewController alloc] init];
NSLog(#"myView init done");
[[self navigationController] pushViewController:tagsView animated:YES];
NSLog(#"myView PUSHED");
// switching this to [self presentViewController:myView animated:YES completion:nil] gets rid of the delay
I have added a number of logs to try to identify exactly when the delay is taking place. The NSLogs from above print quickly as expected:
myView init done
myView PUSHED
Then there is a long delay, probably 20-30 seconds, before all of these lines print:
ViewController loadView begins
ViewController loadView ends
ViewController viewDidLoad begins
ViewController viewDidLoad ends
ViewController viewWillAppear begins
ViewController viewWillAppear ends
willShowViewController
ViewController viewDidAppear here
didShowViewController
All of the ViewController logs are obviously from my UIViewController and *ShowViewController ones are from my UINavigationController delegate. All of the methods of my viewController seem to be running quickly. As I mentioned, if I instead present this same controller at this point in my code there is no delay. Is there a state my UINavigationController can be in to cause this? Any suggestions would be much appreciated.