Cant get values by choosing specific row in UIPickerView - iphone

i have a picker view with array of countries, and my point is, when user tap a specific row i will write some code depends of elements user choose, but, somehow its not working, please look at this:
-(void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component{
if ([countries objectAtIndex:0]){
NSLog(#"You selected USA");
}
}
But problem is, in NSLog is always "You selected USA", regardless of which row i have pick. But, when i put that line of code here:
NSLog(#"You selected this: %#", [countries objectAtIndex:row]);
It show me in console which of country i have choose. But i need to do a things when user tap specific row, and i cant understand how to do this, please help me.

Quick answer: you should use
if ([[countries objectAtIndex:row] isEqualToString:#"USA"]) ...
Nice answer:
Define an enum and use switch-case structure:
// put this in the header before #interface - #end block
enum {
kCountryUSA = 0, // pay attention to use the same
kCountryCanada = 1, // order as in countries array
kCountryFrance = 2,
// ...
};
// in the #implementation:
-(void)pickerView:(UIPickerView *)pickerView
didSelectRow:(NSInteger)row
inComponent:(NSInteger)component
{
switch (row) {
case kCountryUSA:
NSLog(#"You selected USA");
break;
case kCountryCanada:
NSLog(#"You selected Canada");
break;
case kCountryFrance:
NSLog(#"You selected France");
break;
//...
default:
NSLog(#"Unknown selection");
break;
}
}

Related

How to change the picker rows based on another picker's selection?

I have two pickers - country and region. I need to populate the region picker based on the row selected in the country picker. I have arrays to populate both the pickers. I need some help to change the rows of region picker based on the country picker's selection. Any help would be greatly appreciated. Thanks a lot in advance.
Ok You have two pickers lets say countryPicker and regionPicker.
in the delegate method for UIPickerView add one condition
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
NSString *pickerTitle = #"";
if (pickerView == countryPicker)
{
pickerTitle = [countryFeeds objectAtindex:row];
//assigns the country title if pickerView is countryPicker
}
else if (pickerView == regionPicker)
{
pickerTitle = [regionFeeds objectAtindex:row];
//assigns the region title if pickerView is regionPicker
}
return pickerTitle;
}
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
if (pickerView == countryPicker)
{
//selects the region corresponding to the selected country.
//totalRegions is a NSDictionary having country names as keys and array of their regions as values
regionFeeds = [totalRegions objectForKey:[countryFeeds objectAtindex:row]];
//Now reloading the regionPicker with new values.
[regionPicker reloadAllComponents];
}
else if (pickerView == regionPicker)
{
// your code to select a region
}
}
I hope this solves your problem :)
BR, Hari
Are they separate picker views, or one picker view with two columns?
Either way, when you change the value in one picker, just call reloadAllComponents on the other picker (or reloadComponent: if you are using a split picker) and then when it reloads the data from it's data source you can use the value from the first picker to supply the correct region list.
My suggestion is please maintain the country and region in one picker with two components(country,region).If u do like this then we can change the one component values based on another component value.
NSUInteger selectedRow= [CountryPicker selectedRowInComponent:0];
NSString *userchoice =[self pickerView:CountryPicker titleForRow:selectedRow forComponent:0];
This will give you the title for the selected row by the user in country picker
then using the arrays you have to populate names of regions
You can use
- (void)selectRow:(NSInteger)row inComponent:(NSInteger)component animated:(BOOL)animated
on the RegionPicker

How can I get the row number of each components in UIPickerView

How can I get the row number of each component in UIPickerView?
I Have UIPickerView Whit 3 components:
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
And The second question is How can I change width of each component?
You're probably populating the UIPickerView from an array; use the row parameter in a call to
[dataArray objectAtIndex:row];
to get the data. If you need to know the total number of rows, just use [dataArray count]; to get the size of your data source.
EDIT: I forgot that if you're following the protocol, you'll have implemented this method:
-(NSInteger) pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component {
NSInteger numRows = 0;
switch (component) {
case 0:
numRows = 6;
break;
case 1:
numRows = 3;
break;
case 2:
numRows = 2;
break;
default:
break;
}
return numRows;
}
So, you're actually telling the system how many rows for each component. Check this, or go ahead and implement it, and you'll have your answer!
EDIT 2: if you want to get the current selected row in each component, use:
[yourPickerView selectedRowInComponent:1];
as many times as you need. I suggest looping through all components and using this method to get the selected row.

UIPickerView problems

I have a very simple application that use a 2 component UIPickerView that causes me a crash every time I click over it. I dragged it into my view by IB, then hooked up dataSource and delegate to File's Owner. In the .h file:
#interface SettingsViewController : UIViewController <UIPickerViewDataSource, UIPickerViewDelegate> {
While in .m
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)thePickerView {
return 2;
}
- (NSInteger)pickerView:(UIPickerView *)thePickerView numberOfRowsInComponent:(NSInteger)component {
NSInteger value;
if (component == 0) {
value = [tipiDado count];
} else {
value = [numeroDadi count];
}
return value;
}
- (NSString *)pickerView:(UIPickerView *)thePickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component {
if (component == 0) {
return [tipiDado objectAtIndex:row];
} else {
return [numeroDadi objectAtIndex:row];
}
}
- (void)pickerView:(UIPickerView *)thePickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component {
NSLog(#"Selected Dice: %#. Number of Dice: %#", [tipiDado objectAtIndex:row], [numeroDadi objectAtIndex:row]);
}
I dunno why it continues to give me SIGBART or EXC_BAD_ACCESS... I don't know where I'm doing wrong.
Suggestions?
Thanks folks.
It's difficult to answer properly without seeing some more code. When it crashes, you should be able to see exactly what line is causing the crash (look at the call stack on the left). My guess is that either one of your arrays (tipiDado or numeroDadi) are not retained properly or else that the objects stored in them are not of type NSString.
If you update the question with the code you use to initialize them, it will be easier to point out the exact problem.
It's probably because your arrays (tipiDado and numeroDadi) are no longer valid. Maybe they are set up as autoreleased objects?
What you can do, is start in debug mode (debug configuration and with debugger attached) and it should stop right at the line where it crashes.
Try using Allocations with zombo detections / reference counter to see which object is the problem.
In didSelectRow, you are using the same row value to access both arrays. If the arrays are not the same size, you could be accessing an out-of-range item.
You should either check one array only based on the component parameter or to show both selections you can do this instead:
NSInteger tipiDadoRow = [thePickerView selectedRowInComponent:0];
NSInteger numeroDadiRow = [thePickerView selectedRowInComponent:1];
NSLog(#"Selected Dice: %#. Number of Dice: %#",
[tipiDado objectAtIndex:tipiDadoRow], [numeroDadi objectAtIndex:numeroDadiRow]);
I used property/synthesize to initialize them, so when I filled them up with [NSArray arrayWithObjects:...] I haven't added retain but I forget to use self. notation!!
Writing down:
self.tipiDado = [NSArray arrayWithObjects:#"D4",...];
fixed up he problem.

How to handle UIPickerView with two data sources?

is it possible to handle two data sources in the UIPickerView?
I have here a segmented control that would control the display of the picker view.
So, for example, when first segment is clicked, the picker will display person's name. Then, when second segment is clicked, picker will display place's name.
Thanks
Not directly -- the UIPickerView can only have one data source at a time. However, you can switch data source when the user changes the segment. Note that you need to change the delegate of the picker view too, since it is the delegate that supplies the actual content of the picker.
Here is an example where you have two objects that implement UIPickerViewDataSource and UIPickerViewDelegate. The method is invoked when the user clicks on either of the segments in the control:
- (void)segmentedControlValueChanged {
switch (segmentedControl.selectedSegmentIndex) {
case 0:
pickerView.delegate = personDelegate;
pickerView.dataSource = personDelegate;
break;
case 1:
pickerView.delegate = placeDelegate;
pickerView.dataSource = placeDelegate;
break;
default:
break;
}
[pickerView reloadComponent:0];
}
But honestly, I think a better solution is to just have your pickerView:titleForRow:forComponent look at the segmented control.
Assuming you have two NSArrays called persons and places:
- (NSString *)pickerView:(UIPickerView *)pickerView
titleForRow:(NSInteger)row forComponent:(NSInteger)component {
NSString *result;
switch (segmentedControl.selectedSegmentIndex) {
case 0:
result = [self.persons objectAtIndex:row];
break;
case 1:
result = [self.places objectAtIndex:row];
break;
default:
result = #"Error!";
break;
}
return result;
}
- (void)segmentedControlValueChanged {
[pickerView reloadComponent:0];
}
You can check state of segmented control in your UIPickerView delegates (UIPickerViewDelegate and UIPickerViewDataSource) and return necessary values, depending on this state.
And, of course, you can create two objects (conforming to necessary protocols) and just reset delegates on segment state change. But I think this way is generally worse.

How does UIPickerView handle 2+ dials spinning?

If I have a UIPickerView with three components (dials). How does the picker handle two dials spinning simultaneously? For example, the user might flick the first dial, which spins freely and immediately slowly click to a selection on the second dial.
I'm doing the following in the picker. If one dial is spinning, I don't capture its value. I only capture values when the dials spin one at a time.
- (void)pickerView:(UIPickerView *)thePickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component{
if(component == 0){
dateEndCenturyText = (NSString *)[dateCentury objectAtIndex:row];
}
else if(component == 1){
dateEndDecadeText = (NSString *)[dateYear objectAtIndex:row];
}
else if(component == 2){
dateEndYearText = (NSString *)[dateYear objectAtIndex:row];
}
Is there a better way to ensure capture of values even if two dials are spinning?
The most robust solution to this may be to update all three values each time your event fires. You can retrieve the selected row for any component in the UIPickerView using the following method:
UIPickerView selectedRowInComponent:
Returns the index of the selected row in a given component
- (NSInteger)selectedRowInComponent:(NSInteger)component
Hope this helps!