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.
Related
I want to do somenthing with the UIPickerView but I simple can't see how I can solve this problem...
This example is similar to what I want, and easily understandable. I have two simple pickers, with numbers from 0 to 10. Then I have a textfield where the user inserts a number.
What I want is that when the users inserts, for example, 7, and then selects a number in one of the pickers, like 5, the other pickers moves to 2, so that the sum is 7. The same with 0 and 7, 3 and 4.
Basically, how to make a picker move, according to the other picker value selected, based on the input inserted before.
Thank you very much :)
u add array and reload component like this:
- (void)pickerView:(UIPickerView *)thePickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component {
if (component == 0) {
club=[[NSString alloc] initWithFormat:#"%#" , [Nations objectAtIndex:row]];
[secondcomponearray addObject club];
[pickerView reloadComponent:1];
}
try it out suppose you have two UIPickerView like pickerview1 and pickerview2 then you can set the logic like bellow..
Note 1.:- If you used different 2 UIPickerView then use bellow code..
- (void)pickerView:(UIPickerView *)thePickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component {
if (thePickerView == pickerview1) {
if ([yourTextfield.text integerValue] > row) {
int selectVal = [yourTextfield.text integerValue] - row ;
[pickerview2 selectRow:selectVal inComponent:0 animated:YES];
}
else{
int selectVal = row - [yourTextfield.text integerValue] ;
[pickerview2 selectRow:selectVal inComponent:0 animated:YES];
}
}
}
Here what you get just see here if you entered value in UITextField 7 and then select value 5 of pickerview1 then its row number is 4.
here when you minus that 4 from the 7 then what you get is 3 after you set or Select the row number is 3 of pickerview2 and its value is 2.
Note 2.:- If you used 1 UIPickerView and 2 components then use bellow code..
- (void)pickerView:(UIPickerView *)thePickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component {
if (component == 0) {
if ([yourTextfield.text integerValue] > row) {
int selectVal = [yourTextfield.text integerValue] - row ;
[thePickerView selectRow:selectVal inComponent:1 animated:YES];
}
else{
int selectVal = row - [yourTextfield.text integerValue] ;
[thePickerView selectRow:selectVal inComponent:1 animated:YES];
}
}
}
So you got exact output which you want..
i hope you got it...
Enjoy the coding.. :)
Code modified from this post: find pair of numbers in array that add to given sum
The code below loops through to find the possible pairs adding up to the number (the number typed into the textfield), and then in the picker selects the rows with the numbers equalling one of the numbers in the pair. The code assumes that your data source contains the numbers from 0 up to some total in ascending order.
NSInteger number = [[textField text] integerValue];
int i = 0;
int j = number-1
NSMutableArray *possiblePairs = [NSMutableArray array];
while(i < j){
if (i + j == number) {
possiblePairs[] = #[(i), #(j)];
}
else if (a[i] + a[j] < number) i += 1;
else if (a[i] + a[j] > number) j -= 1;
}
[picker1 selectRow:[dataSource indexOfObject:#(i)] inComponent:0];
[picker2 selectRow:[otherDataSource indexOfObject:#(j)] inComponent:0];
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;
}
}
I am trying to get new cells with data from a NSManagedObject to a tableview with a fixed section.
The first section is a fixed section. The second section is where the user can add new data. Displaying the fixed section separate is no problem, as well as showing the dynamic content separate. But when I combine them, I get stuck with this method (see below at the 'rows = ???'). Normally you can fix this easily by doing [array count] but my ManagedObjects are not collected in an array.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
//id <NSFetchedResultsSectionInfo> sectionInfo = [[self.fetchedResultsController sections] objectAtIndex:section];
//return [sectionInfo numberOfObjects];
NSInteger rows = 0;
switch (section) {
case FIXED_SECTION:
rows = 4;
break;
case LIST_SECTION:
{
rows = ???;
break;
}
default:
break;
}
return rows;
}
Either collect the NSManagedObjects in an array (probably an instance variable of the view controller subclass you’re using) or maintain a counter that you increment when adding a cell and decrement when you remove a cell.
The NSFetchedResultsController is what you need, the manual section explains pretty much as you need it
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.
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!