3

Accordingly to this question and the kind answer of KyleC I've implemented a UITableViewController which has many rows relying on a fetch from Core Data. Every row display a simple NSString (name of the object fetched) and has an UIPickerView hidden.

The issue is that it's absolutely evident that when I tap the row in the previous UITableViewController that opens the UITableViewController with picker views there's some delay in the segue transition.

I know this because the previous controllers (they even perform Core Data requests) are not so slow in the transition.

-

Can some UIPickerViews make the transition so slow and pretty ugly? In which mode should I use Instruments to understand which is the slowly-guilty?

More important: if the slowness is derived from the numbers of UIPickerViews how can I optimize this?

I want to clarify that the app is very light and the fetched objects from Core Data are only 4, with 4 UIPickerViews.

Community
  • 1
  • 1
Fred Collins
  • 5,004
  • 14
  • 62
  • 111

1 Answers1

9

It seems that UIPickerViews and UIDatePickers load very slowly from storyboards (and possibly xib's, but I haven't tried). On an iPad Air it's taking around 3 seconds to load a static UITableViewController that contains 4 UIPickerViews and 8 UIDatePickers in "hidden" cells. (3 seconds is an eternity for a native UI running on the latest and greatest hardware!)

The workaround I found is to create the UIPickerViews and UIDatePickers programmatically before the hidden row is revealed. What I did was create empty cells in Interface Builder, link those cells to IBOutlet properties, and then create the DatePickers and Picker views with these methods:

- (UIDatePicker*)datePickerForCell:(UITableViewCell*)cell {
    UIDatePicker * datePicker = [[UIDatePicker alloc] initWithFrame:cell.bounds];
    [datePicker setDatePickerMode:UIDatePickerModeDateAndTime];
    [datePicker addTarget:self action:@selector(pickerDateChanged:) forControlEvents:UIControlEventValueChanged];
    datePicker.hidden = YES;
    [cell addSubview:datePicker];

    return datePicker;
}

- (UIPickerView*)pickerViewForCell:(UITableViewCell*)cell {
    UIPickerView * picker = [[UIPickerView alloc] initWithFrame:cell.bounds];
    [picker setDelegate:self];
    [picker setDataSource:self];
    picker.hidden = YES;
    [cell addSubview:picker];
    return picker;
}

This reduced the load time for the UITableViewController to a few tenths of a second and it doesn't seem to affect the animation of showing a hidden tableview.

Note: I did try creating the pickers in the viewDidAppear: method, but it still seemed to delay the UI.

Anthony F
  • 6,096
  • 4
  • 31
  • 32
  • Great answer there, lots of devs do not notice this lag, but it was nerving me for a while, and took me a bit more to narrow it down to the date pickers. – EmilDo May 01 '14 at 22:08
  • I was getting really slow load times for a uitableview with static cells using a datepicker which had been added through storyboard. I simply deleted my datapickers from the storyboard, added two functions like your datePickerForCell function and two lines calling them from the viewwillappear, everything is much faster. Not as fast as without datepickers, possibly 1/3rd of a second rather than 3 seconds, so that's good. Cheers – LpLrich May 26 '14 at 12:11
  • I couldn't believe this was the correct answer, but I took some measurements that indicate it is indeed correct. Having a date picker in a XIB increased our load time by 1.589 seconds, while creating it programmatically increased it by only 1.007 seconds. Of course, that's still a completely unacceptable amount of time, but it's nice to know. It looks like lazily loading / reusing an instance is the way to go. – Ryan Pendleton Aug 31 '17 at 01:42