picker view - units conversion - iphone

I'm developing an application with a picker view that slide from the bottom (like an action sheet). I need to convert 3 units (litres, us gallons and imperial gallons). The value is taken from a text field but I don't know how to tell the compiler which was the unit to start from.
(ie...the user insert the value in the the text field but if he changes the units (usg or ig), the value in the text field changes accordingly.
this is the array:
NSMutableArray *weightArray = [[NSMutableArray alloc] initWithObjects:#"", #"Ltr",#"Usg",#"Ig",
nil];
self.weightPickerViewArray = weightArray;
[weightArray release];`
this is the picker:
- (void)pickerView:(UIPickerView *)thePickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component {
if (row == 1) {
labelVolume.text = [weightPickerViewArray objectAtIndex:row];
//more code here....
}else if (row == 2){
labelVolume.text = [weightPickerViewArray objectAtIndex:row];
//more code here....
}else if (row == 3){
labelVolume.text = [weightPickerViewArray objectAtIndex:row];
//more code here....
}
how can I tell the compiler which was the value before the selection?

Add a text indicating the units at the end of the string.
- (void)pickerView:(UIPickerView *)thePickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component {
if (row == 1) {
NSString *initalValue = labelVolume.text;
// Do your calculations here based on unit
NSString *updatedValue = urNewValue;
labelVolume.text = updatedValue;
//more code here....
}else if (row == 2){
NSString *initalValue = labelVolume.text;
// Do your calculations here based on unit
NSString *updatedValue = urNewValue;
labelVolume.text = updatedValue;
//more code here....
}else if (row == 3){
NSString *initalValue = labelVolume.text;
// Do your calculations here based on unit
NSString *updatedValue = urNewValue;
labelVolume.text = updatedValue;
//more code here....
}

When you select a row in picker, it call's its delegate method pickerView:didSelectRow:inComponent:
Here, you can can change the value of your text field depending on which row (liters, gallons, etc) user selected.
Please refer the apple's class reference for UIPickerView delegate

If I understand your problem. You want catch event when user change units in your pickerView, pass the information to the view that contains text field and execute conversion.
So you can use NSNotificationCenter (documentation here). In your pickerView when value change put this code :
[[NSNotificationCenter defaultCenter] postNotificationName:#"unitValueChange" object:#"litres"];
In the view that contains UITextField put this code :
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(myMethodToExecute:) name:#"unitValueChange" object:self];
Now when your PickerView launch notification your view launch this method :
-(void)myMethodToExecute:(NSNotification *)notif{
NSString *myUnitSelected = notif.object
}

Related

How to set PickerView selection to UITextFIeld.text using tags?

I currently have a group of text fields being created and under a certain condition instead of a keyboard the text field will display a pickerview. Once a selection is made, I need to populate the text field with the selection. I have created tags on all of the text fields, the problem is I don't know the syntax to select the text field I want.
Here is the code for creating the text field with the pickerview.
else if([input.controlTypeName compare:#"RadioButton"] == NSOrderedSame){
UITextField *pickerViewtext = [[UITextField alloc] initWithFrame:CGRectMake(x, y, 280, 31)];
pickerViewtext.borderStyle = UITextBorderStyleRoundedRect;
pickerViewtext.textColor = [UIColor blackColor]; //text color
pickerViewtext.font = [UIFont systemFontOfSize:17.0]; //font size
pickerViewtext.placeholder = placeholder; //place holder
pickerViewtext.backgroundColor = [UIColor whiteColor]; //background color
pickerViewtext.autocorrectionType = UITextAutocorrectionTypeNo; // no auto correction support
pickerViewtext.tag = i; //tag the textfields for future data collection
pickerViewtext.keyboardType = UIKeyboardTypeDefault; // type of the keyboard
pickerViewtext.returnKeyType = UIReturnKeyDone; // type of the return key
pickerViewtext.clearButtonMode = UITextFieldViewModeWhileEditing; // has a clear 'x' button to the right
pickerViewtext.delegate = self; // let us be the delegate so we know when the keyboard's "Done" button is pressed
UIPickerView *radioPicker = [[UIPickerView alloc] initWithFrame:CGRectZero];
radioPicker.delegate = self;
radioPicker.showsSelectionIndicator = YES;
radioPicker.tag = i;
radioTag = i;
[radioSize addObject:[NSNumber numberWithInt:5]];
[radioList addObject:input.sourceText];
pickerViewtext.inputView = radioPicker;
[inputsView addSubview:pickerViewtext];
y = y + 50;
}
I'm basically at a loss for what to put into my
- (void)pickerView:(UIPickerView *)pickerView didSelectRow: (NSInteger)row inComponent: (NSInteger)component {
// Handle the selection
}
delegate method. I thought about using the 'radioTag' variable as some kind of global. But with the possibility of multiple textfields that use a pickerview, this would only cause all of the picker views to link back to the same text field. And most tag examples I have found don't seem to apply to this or are too old and the syntax has changed. Any help would be great.
Thanks.
UITextField *textField = (UITextField *)[inputsView viewWithTag:pickerView.tag];
I have a similar type of app that uses the following and this may point you in the right direction
NSString *aVal = [activities objectAtIndex:[_emailPicker selectedRowInComponent:0]];
a=[aVal intValue];
NSString *bVal = [activities objectAtIndex:[_emailPicker selectedRowInComponent:1]];
b=[bVal intValue];
NSString *cVal = [activities objectAtIndex:[_emailPicker selectedRowInComponent:2]];
c=[cVal intValue];
It has three components, you may just use component:0, or whatever you need. The second part of each is converting to an intValue [integer value] which you may not need. Others might.
The values were placed into a mutableArray and "entered" into the picker view using:
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent: (NSInteger)component
{
if (component == 0) {
return [activities count];
}
else if (component == 1) {
return [feelings count];
}
else if (component==2) {
return [addresses count];
}
else return 0;
}
where my three arrays were called activities, feelings and addresses and count is the number of entries in each array. I hope this gets you down the path a little further.

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

Show UIAlertView if UITableView is empty

I have RSS, and the UITableView loads data from it, how can I show UIAlertView if the UITableView is empty, but not by count of an array because the array is different every time it is refreshed, is there some kind of function which will check if UITableView is empty after it completes drawing?
You can query the UITableView itself. So assuming you have a single section you could do the following ...
// Reload the tableview
[tableView reloadData];
// Test the number of rows in the first section
if ([tableView numberofRowsInSection:0] == 0) {
// Display UIAlertView here
}
EDIT; Based on the comments below ...
In your header file (.h) iVar declarations ...
int feedCount;
int feedsParsed;
In your implementation ...
- (void)refresh {
feedCount = 0;
feedsParsed = 0;
[feedParser stopParsing];
self.title = #"Refreshing...";
[parsedItems removeAllObjects];
for (NSString *imePredmeta in [Data variables].mojiPredmeti) {
... // I've removed these lines for brevity but they are still required
[feedParser parse];
feedCount += 1;
}
// Delete everything else after this line
}
- (void)feedParserDidFinish:(MWFeedParser *)parser {
feedsParsed += 1;
if (feedsParsed == feedCount) {
[self.tableView reloadData];
if ([self.tableView numberofRowsInSection:0] == 0) {
// Fade out tableview and display alert here as we now know for
// sure that there are no more feeds to parse and we definitely
// have nothing to display
}
}
}
You will need to loop round the array and check to determine if there are no results.
Please post your existing tableview code if you want a more explicit answer.
edit: micpringle answer above is better.

How to place the morethan one pickerviews in view?

Hai,In my app i want to place the 4 pickerviews.And i place the one segment control with 3 segments.If we click on first segment then firstpicker will be display.Likewise remaining pickers are display for remaining segments.But,only first picker will be displayed and remaining pickers are not show components and rows.Only display black screen.Please provide any help.Please urgent.
To again call the delegates, call the following line
[pickerview reloadComponent];
create outlet and make use of hidden property...means if you tap on first segment make first picker as highlighted and similarly for other segments with respective pickers...
do you want to resize ??
Edit: added code from below for formatting purposes
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView {
return ( pickerView == picker1 ? 2 : 3 );
}
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component { NSArray *values = ( pickerView == picker1 ? values1 : values2 );
return [values count];
}
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component {
NSArray *values = ( pickerView == picker1 ? values1 : values2 );
return [values objectAtIndex: row];
}
check like this..

Expanding and retracting dropdown list in iPhone app

I'm starting off developing an iPhone app. I need to present a drop down box for the customer to pick a value which will essentially be sent downstream to a database upon submit. I'm clearly using a UIPickerView for the drop down list, built from IB.
Once my view loads, the Drop down list is enabled, with all values showing.
Question is:
Can I only expand the drop down list once it's clicked?
Can I retract the list once the user selects a value?
I'm thinking very web-centric in terms of drop-downs, but I could have this all wrong.
Your view controller needs to implement the UIPickerViewDataSource as well as the UIPickerViewDelegate. In the XIB of the UIPickerView you need to link the File's Owner with the UIPickerView's delegate and datasource.
Like in the UITabelDataSource you need to provide the number of components (table: sections) inside [numberOfComponentsInPickerView]. Then you need to provide the number of rows for each component in [numberOfRowsInComponent]. Finally you need to provide the title for the each entry inside [titleForRow].
Now to bring everything to life you can use [didSelectRow] to load the next component if the previous one was selected.
Attention: UIPickerView has a little bug not to call [didSelectRow] when the component is filled / changed. In order to make it work more smoothly I added a "None" entry as the first entry which is a non-selection and does not cause the next component to be loaded.
This is a rudimentary code:
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView {
return 3; // Number of Components aka Columns
}
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component {
if( component == 0 ) {
return [self.firstColumnEntries count] + 1;
} else if( component == 1 ) {
return [self.secondColumnEntries count] + 1;
} else if( component == 2 ) {
return [self.thirdColumnEntries count] + 1;
}
return 0;
}
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component {
NSLog( #"titleForRow(), component: %d, row: %d", component, row );
NSDictionary *item = nil;
if( row == 0 ) {
return #" --- ";
} else {
int correctedRow = row - 1;
if( component == 0 ) {
item = [self.firstColumnEntries objectAtIndex:correctedRow];
} else if( component == 1 ) {
item = [self.secondColumnEntries objectAtIndex:correctedRow];
} else if( component == 2 ) {
item = [self.thirdColumnEntries objectAtIndex:correctedRow];
}
return [item objectForKey:#"name"]; // My objects are NSDictionarys
}
}
- (void) pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component {
DLog( #"SSVC.didSelectRow(), component: %d, row: %d", component, row );
ActionRequest *action = nil;
if( row == 0 ) {
if( component == 0 ) {
[self refreshFirstColumn:self.firstColumnEntries];
} else if( component == 1 ) {
...
}
} else {
// Last Column is selected. Now selection is complete
...
}
}
Because the UIPickerView takes away a lot of space and you cannot change it size I would recommend to place it on an additional UIView (make the rest transparent) and display it when the user selected the field that is assigned to the value (UITextField). When the selection is done (either when last value is selected or when the user enter a button) you let the View disappear and set the value onto the UITextField. Make sure that the UITextField cannot be edited and that entering it make the View with the Picker View appear. When done make sure that you also move to the next field.
You have a couple options:
Probably easiest for a beginner: push a new view (either as a modal view or onto the nav stack) that presents the list either as a table view where they click the item they want or as a pickerView where it scrolls.
Review the twitter app 'my profile' view. While I haven't done this personally, I think it's simply using the didSelectRowAtIndex to determine which section the user clicked and then filling an array of values for that section before calling [tableView reloadData]