Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

1458279

Suspended
Original poster
May 1, 2010
1,601
1,521
California
I'm trying to have to different UIpickerViews with different methods, however every example I see, use the same methods:

Code:
- (NSString *)pickerView:(UIPickerView *)picker titleForRow:(NSInteger)row forComponent:(NSInteger)component;
{
    return [[self.pickerData objectAtIndex:component] objectAtIndex:row];
}

The closest example I can find, suggest to use the .tag to ID each different pickerView. Then use an "if" inside the method to determine which picker is which.

The Apple docs say:
A UIPickerView object requires the cooperation of a delegate for constructing its components and a data source for providing the numbers of components and rows. The delegate must adopt the UIPickerViewDelegate protocol and implement the required methods to return the drawing rectangle for rows in each component.

and

The UIDatePicker class uses a custom subclass of UIPickerView to display dates and times.

But I can't seem to find any examples of this.

Can anyone point to an example of a UIPickerView done programmatically that uses a custom UIPickerViewDelegate?

My guess it would involve changing myPicker.delegate = self; to myPicker.delegate = _____ However I can't seem to find an example in the Apple docs or StackOverflow.

I probably should have made it clear that I wanted this to not call the standard delegate so that it doesn't change the other pickers.
 

1458279

Suspended
Original poster
May 1, 2010
1,601
1,521
California
Ok, looks like it must be subclassed (from Stackoverflow):

All of your UIPickerViews will be calling UIPickerViewDelegate methods, meaning -(NSInteger)weightpickerView:(UIPickerView *)weightPickerView numberOfRowsInComponent: (NSInteger)component will not be called unless you are subclassing and creating your own methods (which I believe you are not), i.e.

Code:
-(NSInteger)pickerView:(UIPickerView *)pickerView NumberOfRowsInComponent: (NSInteger)component {
  if([pickerView isEqual: agePickerView]){
   return [agePickerArray count];
  }else if([pickerView isEqual: weightPickerView]){
   return [weightPickerArray count];
  }else return 0;
}

The problem I see is that he's still calling pickerView, which is no better than this:
Code:
weightPickerView.tag = 100; //set the tag

if(pickerView.tag == 100) //check which picker it is

Ok, looks like he gives a partial example. From what he says, I need to subclass the pickerView methods. Anyone have a complete example of doing this?
 
Last edited:

Punkjumper

macrumors member
Jan 12, 2013
48
3
what I've done when I have multiple pickers that are displayed inline in a tableView is make a class UIPickerViewDataSource that has the standard methods
.m file
Code:
@implementation UIPickerViewDataSource
-(instancetype)initWithModelObject:(id)obj{
    self = [super init];
    if (self) {
        
    }
    return self;
}

-(NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView{
    if (!_componentNumber) {
        return 1;
    }else{
        return _componentNumber;
    }
}
-(NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component{
    return [_pickerDataSource count];
}

-(NSString*)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component{
    
    return [_pickerDataSource objectAtIndex:row];
}
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component{
    _selectedRow = row;
    [self.delegate pickerDidSelectObject];
    
}
-(id)selectedObject{
    return [_dataObjects objectAtIndex:_selectedRow];
}
-(id)selectedString{
    return [_pickerDataSource objectAtIndex:_selectedRow];
}
.h file

Code:
@protocol UIPickerDataSourceDelegate<NSObject>
-(void)pickerDidSelectObject;
@end;

@interface UIPickerViewDataSource : NSObject <UIPickerViewDataSource, UIPickerViewDelegate>
@property (retain, nonatomic) id<UIPickerDataSourceDelegate>delegate;

@property (nonatomic, strong)NSArray *pickerDataSource;
@property(nonatomic, strong)NSArray *dataObjects;
@property (readwrite, assign)NSUInteger selectedRow;
@property (nonatomic, assign)NSInteger componentNumber;

//subclass must override
-(instancetype)initWithModelObject:(id)obj;
-(id)selectedObject;
-(id)selectedString;
@end

@end

then I would subclass that for each UIPicker and have custom methods that that picker needed to load its data

Code:
@implementation TripTitlesPickerDataSource

-(instancetype)initWithModelObject:(id)obj{
    self = [super init];
    if (self) {
        if ([obj isKindOfClass:[Route class]]) {
            _route = obj;
            self.pickerDataSource = [self loadData];
        }
    }
    return self;
}

-(NSArray *)loadData{

}
@end

and finally in the class where I want to use my UIPicker in a tableViewCell I do

Code:
-(void)configureCustomPickerCell:(CustomPickerViewCell *)cell atIndexPath:(NSIndexPath *)indexPath{
    UIPickerViewDataSource *source;
    if (pickerIndex == RateIndex) {
        source = _reimbursePickerSource;
    }
    if (pickerIndex == tripNameIndex) {
        source = _tripTitlesPickerSource;
    }
    if (pickerIndex == categoryIndex) {
        source = _categoryPickerDataSource;
    }
    cell.pickerView.delegate = source;
    cell.pickerView.dataSource = source;
    

}
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.