I've set up a UIPickerView successfully, but I'm wondering about the best way to handle the case when the data is initially empty. For my current iteration I use the following code for the pickerdelegate
-(NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
if ([flash_cards count])
{
return [[flash_cards allKeys] objectAtIndex:row];
}
return #"";
}
where
flash_cards = NSMutableDictionary *
Whenever I try to scroll it creates an error of indexoutofbounds which is only logical. How do I handle the case of an empty array?
EDIT:
Also as part of the code I implemented the following
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponen: (NSInteger)component
{
return [flash_cards count];
}
#pragma mark Picker Data Source Methods
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
return 1;
}
To solve this problem you should return 1 instead 0 in the method numberOfRowsInComponent from the UIPickerViewDataSource when the array is empty, like the example below:
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
return [self.myArray count] == 0 ? 1 : [self.myArray count];
}
You should also implement the UIPickerViewDataSource methods:
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
You can still use flash_cards (or [flash_cards count]) to derive the return values of these methods; if your data is empty, you can return 0, then later call -reloadAllComponents on your picker view when you get data loaded.
Related
I have two UIPickerViews With data being pulled from an array though I can't seem to program them separately. Here is the code that I am using for my UIPickerViews:
-(NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component {
return [treatments count];
}
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView {
return 1;
}
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
return[[treatments objectAtIndex:row]valueForKey:#"treatmentName"];
}
-(void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component {
_buttonText.text = [[treatments objectAtIndex:row]valueForKey:#"treatmentName"];
if (![_buttonText.text isEqual: #"Pick a Treatment Name"]) {
_buttonText.textColor = [UIColor blackColor];
}
}
-(NSInteger)nursePicker:(UIPickerView *)nursePicker numberOfRowsInComponent:(NSInteger)component {
return [nurses count];
}
- (NSString *)nursePicker:(UIPickerView *)nursePicker titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
return[[nurses objectAtIndex:row]valueForKey:#"nurseName"];
}
When I run the code the pickers show the same data
Thanks in advance
Store a reference to your two picker views and use the UIPickerView that is passed as an argument to the datasource methods in order to determine which picker view you are using.
-(NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component {
if (pickerView == self.nursePicker) {
return [nurses count];
}
else if (pickerView == self.treatmentPicker) {
return [treatments count];
}
}
Same idea for every datasource method
You should put a BOOL to check the data. Create a BOOL called treatment and when the first picker is available set the BOOL to YES and when the second is available set the BOOL to NO. Then check in your methods to see which picker is their and put in the data.
#interface NotesViewController ()
{
BOOL treatment;
}
- (void)firstPickerComesUP
{
treatment = YES;
}
- (void)secondPickerComesUP
{
treatment = NO;
}
PickerView delegate method...
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
return 1;
}
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
if (didSelectedRow ==1)
{
strChkDistanceValue = [arrDistance objectAtIndex:row];
}
else
{
strChkDateRangeValue = [arrDateRange objectAtIndex:row];
}
}
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component;
{
if(didSelectedRow ==1)
{
return [arrDistance count];
}
else
{
return [arrDateRange count];
}
}
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component;
{
if(didSelectedRow ==1)
{
strChkarray =#"arrDistance";
return [arrDistance objectAtIndex:row];
}
else
{
strChkarray =#"arrDateRange";
return [arrDateRange objectAtIndex:row];
}
}
above code I am use...
I am using the pickerview in tableview... there are two picker views...
when i am use the first picker view the first picker view array shows in picker when i am select 3rd row in picker view after i select the 2nd picker view then show the second array list but second array list show start with 3rd row...same to 1st picker...
but i want to show at first row of array in pickerviw..
please help me...
Thanks & regards
Rahul Virja
You should use below method of UIPickerView to select a particular row.
- (void)selectRow:(NSInteger)row inComponent:(NSInteger)component animated:(BOOL)animated;
I got a string as mild,medium,hot.I split the string with comma as separator.I need to print it in a pickerView too.
I used the following code and got List count as 3 successfully.
NSString *spList=[mdict objectForKey:#"spicinesstype"];
NSArray *list = [spList componentsSeparatedByString:#","];
NSLog(#"List count:%d",[list count]);
return [list count];
But how could I display all 3 items in pickerview
You should set your class as the delegate of the picker view, Then implement these 3 delegate methods for your picker
- (NSInteger)pickerView:(UIPickerView *)thePickerView numberOfRowsInComponent:(NSInteger)component {
return [array count];
}
- (NSString *)pickerView:(UIPickerView *)thePickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component {
return [array objectAtIndex:row];
}
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)thePickerView {
return 1;
}
First you need to implement UIPickerViewDelegate and UIPickerViewDataSource by putting them on the end of the #interface line of the header file of your view controller.
Like this: #interface MyViewController : UIViewController <UIPickerViewDelegate, UIPickerViewDataSource>
Next you need to set your view controller as the delegate and data source of you picker view. You can either do this in the - (void)viewDidLoad method of your view controller by adding the lines:
myPickerView.delegate = self;
myPickerView.dataSource = self;
Or you can link it up in Interface Builder if you are using that.
Then you need to implement these delegate methods in your View Controller source file.
(NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView;
{
return 1;
}
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
// whatever you want to happen when a row is selected.
}
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component;
{
return [list count];
}
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component;
{
return [list objectAtIndex:row];
}
I'm new to Objective-C, and I already have a button with a function to go when the press the button. In the UIPickerView it has lots of numbers going up until who knows how long. I used this code:
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView {
return 3;
}
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component {
// Near-infinite number of rows.
return NSIntegerMax;
}
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component {
return [NSString stringWithFormat:#"%d", row];
}
I just need the number that was entered in all three components.
The value for each component is found in:
[yourPicker selectedRowInComponent:x]
where x is the component number (0, 1, or 2 in your case).
I want my picker view can display 1 - 200. but I think it is too much memory, if I assign an Array in this view:
self.myLargeView = [[NSArray alloc] initWithObjects:#"1 unit", #"2 units", .... ..., #"199 units" #"200 units", nil]; //code skipped
How can I reduce the memory load in application? any ideas?
If you want your picker view just to display an incremented number then you might use something like this:
#define kPickerValuesAmount 200
#pragma mark -
#pragma mark UIPickerViewDataSource methods
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView {
return 1;
}
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component {
return kPickerValuesAmount;
}
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component {
return [NSString stringWithFormat:#"%i unit%#", (row + 1), (row == 0 ? #"" : #"s")];
}
If the user has to just pick a number from 1 to 200, why not use a UISlider instead?
An array of 200 short NSStrings will not cause you any memory problems. It just takes up a few kilobytes.