Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UIDatePicker slows things down

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!

like image 830
MCKapur Avatar asked Jun 24 '12 05:06

MCKapur


2 Answers

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.

like image 27
Pius Uzamere Avatar answered Nov 08 '22 23:11

Pius Uzamere


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];
like image 111
Raz Avatar answered Nov 09 '22 00:11

Raz