I have used Interface Builder in Xcode 4.02 to add two UIPickerViews in a View. They are connected to the same delegate and datasource (UIViewController). In my .h file I have also declared UIPickerViews and connected them as reference outlets, as in many examples.
In viewForRow I use the same NSMutable data array of UILabels to return the appropriate values (this array was populated in viewDidLoad).
However, I find that no Label appears in both UIPickerViews at the same time. For example, when the app starts each UIPickerView should show elements 0, 1 and 2. viewForRow is invoked 3 times for each UIPickerView but only the view which invokes viewForRow second will display the first 3 rows. The other UIPickerView is blank. If I scroll the first view down to, say, the 6th element and then back to the first, the view will then show the first 3 elements but the second view (the one that did show the first 3 rows) now shows nothing. Specifically, no data array element will appear in both UIPickerViews at the same time.
Is this expected? Should each UIPickerView have its own backing array – if you’re using them? Aren’t all these returned views just pointers? It’s as if each array element can only be displayed (pointed to) at most once at any time.
If I use two separate data arrays then there appear to be no problems. But it does mean extra memory and extra coding.
Note: in viewForRow I have code to set the label’s size:
UILabel *xx = (UILabel *)[self.array1 objectAtIndex:row];
CGSize rowSize = [thePickerView rowSizeForComponent:component];
CGRect labelRect = CGRectMake (0, 0, rowSize.width, rowSize.height);
[xx setFrame:labelRect];
The values set here do not change even when the row later appears to be blank.
Multiple picker views can share the same data source but a view (
UILabelin this case) can only have one superview.You cannot use the same labels in both pickers and there’s probably little reason to store them in an array of your own anyway. A better approach would be to create a separate label in the
viewForRowmethod and have just an array with the labels’ content (e.g. anNSString).In your current implementation, when you return the label, the picker adds it to its own view hierarchy which implicitly removes it from any view it was in before (your other picker).