I have spent a good time and concluded that UIDatePicker
slows presentModalViewController:
down by a few seconds. I have a view controller with two buttons and a date picker. In another class, I present this view controller with this code:
RandomClass *class = [[RandomClass alloc] init];
[class setModalTransitionStyle: UIModalTransitionStyleCrossDissolve]; //an animation
[self presentModalViewController: class animated: YES];
[class release];
I have removed the date picker in RandomClass
and noticed that I can present RandomClass
fairly quickly, when I insert a date picker inside the view, it slows things down again. I have tried to add the date picker programmatically, and presenting the modal view controller in a different thread, but there is still lag.
Do you have the same problem? Do you know how to fix it? I would really appreciate your answers and help. Thanks!
To solve performance problems with UIDatePicker, create your picker programmatically and only in viewDidAppear. If you create it in viewDidLoad, for example, the slow instantiation will block the view from appearing on screen.
I was experiencing the same sluggish performance with modal view presentation. I arrived to a solution by sacrificing some memory in favour of performance.
BACKGROUND: My app was using the Model-View-Controller-Store model. The Store was a singleton which was taking care of my model, hence it was virtually accessible from any of my classes once it was instantiated. I was using the Store class to keep around certain expensive classes (such as NSCalendar, NSDateFormatter etc) through properties.
SOLUTION:
I crated a UIDatePicker property in the Store singleton, which allowed it to be accessed through any class.
In the interface of the Singleton:
@property (strong, nonatomic) UIDatePicker *datePicker;
In the implementation of the Singleton I implemented a getter for the datePicker.
- (UIDatePicker *)datePicker
{
if (!_datePicker) {
_datePicker = [[UIDatePicker alloc] init];
}
return _datePicker;
}
This ensured datePicker was being created only once, and it can be accessed from anywhere in my app.
Now in the viewDidLoad method of the class where you would need to use the picker, get the property through the getter method:
UIDatePicker *aDatePicker = [[MySingleton shareInstance] datePicker];
// Set it's location.
[aDatePicker setFrame:CGRectMake(0.0, 236.0, self.view.frame.size.width, 216.0)];
// Connect to any actions
[aDatePicker addTarget:self action:@selector(datePickerValueChanged:) forControlEvents:UIControlEventValueChanged];
// Add it to you view
[self.view addSubview:[[MySingleton shareInstance] datePicker]];
The sluggish behaviour will happen for the first time when the date picker is being created. Every other time the modal view will appear blazingly fast (depending what else you had in the view).
Essentially I was creating a global variable and keeping it around so that I didn't have to create it every time, at the cost of memory. The performance difference made it worthwhile in my apps case.
NOTE: There is one caveat to watch for though. Since the datePicker will most likely outlive the modal view, it is imperative to make sure that the datePicker is not pointing to any deallocated memory.
So if "self" was assigned as a target in viewDidLoad:
[aDatePicker addTarget:self action:@selector(datePickerValueChanged:) forControlEvents:UIControlEventValueChanged];
It's important that in a method such as viewDidDisappear to add this code to prevent a crash:
[aDatePicker removeTarget:self action:@selector(datePickerValueChanged:) forControlEvents:UIControlEventValueChanged];
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With