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

johnnyfla123

macrumors newbie
Original poster
Jun 15, 2013
21
0
Alright So i am experimenting with uipickerviews to learn more about Xcode and develop a simple app. I have everything the way i want it except one thing the outputs. The way i have it setup is it will provide the output using label. I can get it to give an output but i need it to give an output based on the selection and i am now stuck at a dead end here.


the app converts quantities like grams to oz, pound to gram, etc. I want to simple make it so its like this: in component 1 you select grams. then in component 2 you select pounds. and the output would be: " 1 pound is equal to 453 grams" and it would display this text on the output label I have the label linked and setup so it can give outputs its jut the actual code i cant figure out without messing up.

here is my .h:

Code:
#import <UIKit/UIKit.h>
#define kFillingComponent  0
#define kBreadComponent  1


@interface FirstViewController : UIViewController
<UIPickerViewDelegate, UIPickerViewDataSource>{
    IBOutlet UIPickerView *doublePicker;
    NSArray *fillingTypes;
    NSArray *breadTypes;
}

@property (nonatomic,retain)  UIPickerView *doublePicker;
@property (nonatomic,retain)  NSArray *fillingTypes;
@property (nonatomic,retain)  NSArray *breadTypes;
@property (nonatomic,retain)  IBOutlet UILabel *OutputLabel;

@end

and my .m

Code:
#import "FirstViewController.h"
#import "NewViewController.h"

@implementation FirstViewController

@synthesize doublePicker;
@synthesize fillingTypes;
@synthesize breadTypes;
@synthesize OutputLabel;


// The designated initializer. Override to perform setup that is required before the view is loaded.
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
    if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) {
        // Custom initialization
    }
    return self;
}


// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
	NSArray *breadArray = [[NSArray alloc] initWithObjects:
                           @"1 Gram",@"1/8 Ounce",@"1/4 Ounce",@"1/2 Ounce",@"1 Ounce",@"1/4 Pound",@"1 Pound",nil];
   	self.breadTypes = breadArray;
	[breadArray release];
	
	NSArray *fillingArray = [[NSArray alloc] initWithObjects:
                             @"1Gram",@"1/8 Ounce",@"1/4 Ounce",@"1/2 Ounce",@"1 Ounce",@"1/4 Pound",@"1 Pound",nil];
	self.fillingTypes = fillingArray;
	[fillingArray release];
	[super viewDidLoad];
}

// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
    // Return YES for supported orientations
    return (interfaceOrientation == UIInterfaceOrientationPortrait);
}


- (void)didReceiveMemoryWarning {
	// Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];
	
	// Release any cached data, images, etc that aren't in use.
}

- (void)viewDidUnload {
    [self setOutputLabel:nil];
}


- (void)dealloc {
	[doublePicker release];
	[breadTypes release];
	[fillingTypes release];
    [super dealloc];
}


-(NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
	return 2;
}

-(NSInteger)pickerView:(UIPickerView *)pickerView
numberOfRowsInComponent:(NSInteger)component
{
	if (component == kBreadComponent)
		return[self.breadTypes count];
    return[self.fillingTypes count];
}

-(NSString *)pickerView:(UIPickerView *)pickerView
            titleForRow:(NSInteger)row
           forComponent:(NSInteger)component
{
	if (component == kBreadComponent)
    return [self.breadTypes objectAtIndex:row];
	return [self.fillingTypes objectAtIndex:row];
}

-(void) pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component {
    
    NSString *breadTypesSelected = [breadTypes objectAtIndex:[pickerView selectedRowInComponent:0]];
    NSString *fillingTypesSelected = [fillingTypes objectAtIndex:[pickerView selectedRowInComponent:1]];
    
    if(breadTypesSelected == 0 && fillingTypesSelected == 0){[OutputLabel setText:[NSString stringWithFormat:@"test"]];}
    else if(breadTypesSelected == 0 && fillingTypesSelected == 0){[OutputLabel setText:[NSString stringWithFormat:@"test2"]];}
    
        
}


@end


i tired many different ways but i cant seem to get it. sorry for the long post i just want to be as clear as possible of what I'm trying to accomplish.

Thanks in advance
 
Last edited:

Duncan C

macrumors 6502a
Jan 21, 2008
853
0
Northern Virginia
It's early and I'm low on coffee, so I may miss stuff.

Your code looks reasonable except for the if statement in your didSelectRow:inComponent: method.

You use selectedRowInComponent to get the currently selected items and build 2 strings. Then you compare your strings to zero, which does not make sense.

Better to fetch the integer index for both components and use that:

Code:
    int sourceUnit = [pickerView selectedRowInComponent:0]];
    NSString *sourceUnitName = [breadTypes objectAtIndex: sourceUnit];

    int destUnit = [pickerView selectedRowInComponent:1]];
    NSString *destUnitName = [fillingTypes objectAtIndex: destUnit];

    float resultValue = <insert your calculation here>
    NSString *result = [NSString stringWithFormat: @"One %@ equals %.2f %@", sourceUnitName, destUnitName, resultValue];


Alright So i am experimenting with uipickerviews to learn more about Xcode and develop a simple app. I have everything the way i want it except one thing the outputs. The way i have it setup is it will provide the output using label. I can get it to give an output but i need it to give an output based on the selection and i am now stuck at a dead end here.


the app converts quantities like grams to oz, pound to gram, etc. I want to simple make it so its like this: in component 1 you select grams. then in component 2 you select pounds. and the output would be: " 1 pound is equal to 453 grams" and it would display this text on the output label I have the label linked and setup so it can give outputs its jut the actual code i cant figure out without messing up.

here is my .h:

Code:
#import <UIKit/UIKit.h>
#define kFillingComponent  0
#define kBreadComponent  1


@interface FirstViewController : UIViewController
<UIPickerViewDelegate, UIPickerViewDataSource>{
    IBOutlet UIPickerView *doublePicker;
    NSArray *fillingTypes;
    NSArray *breadTypes;
}

@property (nonatomic,retain)  UIPickerView *doublePicker;
@property (nonatomic,retain)  NSArray *fillingTypes;
@property (nonatomic,retain)  NSArray *breadTypes;
@property (nonatomic,retain)  IBOutlet UILabel *OutputLabel;

@end

and my .m

Code:
#import "FirstViewController.h"
#import "NewViewController.h"

@implementation FirstViewController

@synthesize doublePicker;
@synthesize fillingTypes;
@synthesize breadTypes;
@synthesize OutputLabel;


// The designated initializer. Override to perform setup that is required before the view is loaded.
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
    if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) {
        // Custom initialization
    }
    return self;
}


// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
	NSArray *breadArray = [[NSArray alloc] initWithObjects:
                           @"1 Gram",@"1/8 Ounce",@"1/4 Ounce",@"1/2 Ounce",@"1 Ounce",@"1/4 Pound",@"1 Pound",nil];
   	self.breadTypes = breadArray;
	[breadArray release];
	
	NSArray *fillingArray = [[NSArray alloc] initWithObjects:
                             @"1Gram",@"1/8 Ounce",@"1/4 Ounce",@"1/2 Ounce",@"1 Ounce",@"1/4 Pound",@"1 Pound",nil];
	self.fillingTypes = fillingArray;
	[fillingArray release];
	[super viewDidLoad];
}

// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
    // Return YES for supported orientations
    return (interfaceOrientation == UIInterfaceOrientationPortrait);
}


- (void)didReceiveMemoryWarning {
	// Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];
	
	// Release any cached data, images, etc that aren't in use.
}

- (void)viewDidUnload {
    [self setOutputLabel:nil];
}


- (void)dealloc {
	[doublePicker release];
	[breadTypes release];
	[fillingTypes release];
    [super dealloc];
}


-(NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
	return 2;
}

-(NSInteger)pickerView:(UIPickerView *)pickerView
numberOfRowsInComponent:(NSInteger)component
{
	if (component == kBreadComponent)
		return[self.breadTypes count];
    return[self.fillingTypes count];
}

-(NSString *)pickerView:(UIPickerView *)pickerView
            titleForRow:(NSInteger)row
           forComponent:(NSInteger)component
{
	if (component == kBreadComponent)
    return [self.breadTypes objectAtIndex:row];
	return [self.fillingTypes objectAtIndex:row];
}

-(void) pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component {
    
    NSString *breadTypesSelected = [breadTypes objectAtIndex:[pickerView selectedRowInComponent:0]];
    NSString *fillingTypesSelected = [fillingTypes objectAtIndex:[pickerView selectedRowInComponent:1]];
    
    if(breadTypesSelected == 0 && fillingTypesSelected == 0){[OutputLabel setText:[NSString stringWithFormat:@"test"]];}
    else if(breadTypesSelected == 0 && fillingTypesSelected == 0){[OutputLabel setText:[NSString stringWithFormat:@"test2"]];}
    
        
}


@end


i tired many different ways but i cant seem to get it. sorry for the long post i just want to be as clear as possible of what I'm trying to accomplish.

Thanks in advance
 

johnnyfla123

macrumors newbie
Original poster
Jun 15, 2013
21
0
alright so i plugged it in and changed what xcode wanted to. i don't know if
Code:
 if(sourceUnit == 0 && destUnit == 0){[OutputLabel setText:[NSString stringWithFormat:@"test"]];}

was supposed to stay or not so i left it and modified it to match your stuff.
Code:
    int sourceUnit = [pickerView selectedRowInComponent:0];
    NSString *sourceUnitName = [breadTypes objectAtIndex: sourceUnit];
    
    int destUnit = [pickerView selectedRowInComponent:1];
    NSString *destUnitName = [fillingTypes objectAtIndex: destUnit];
    
    float resultValue = destUnit * sourceUnit;
    NSString *result = [NSString stringWithFormat: @"One %@ equals %@ %f", sourceUnitName, destUnitName, resultValue];
    
    if(sourceUnit == 0 && destUnit == 0){[OutputLabel setText:[NSString stringWithFormat:@"test"]];}


I'm sure i did the calculation part wrong. i just cant grasp how to get each value to give a specific text output. I cant even find an example that fits what i'm trying to do here. Ive seen it done on an app so i know its entirely possible.
 
Last edited:

Duncan C

macrumors 6502a
Jan 21, 2008
853
0
Northern Virginia
alright so i plugged it in and changed what xcode wanted to. i don't know if
Code:
 if(sourceUnit == 0 && destUnit == 0){[OutputLabel setText:[NSString stringWithFormat:@"test"]];}

was supposed to stay or not so i left it and modified it to match your stuff.
Code:
    int sourceUnit = [pickerView selectedRowInComponent:0];
    NSString *sourceUnitName = [breadTypes objectAtIndex: sourceUnit];
    
    int destUnit = [pickerView selectedRowInComponent:1];
    NSString *destUnitName = [fillingTypes objectAtIndex: destUnit];
    
    float resultValue = destUnit * sourceUnit;
    NSString *result = [NSString stringWithFormat: @"One %@ equals %@ %f", sourceUnitName, destUnitName, resultValue];
    
    if(sourceUnit == 0 && destUnit == 0){[OutputLabel setText:[NSString stringWithFormat:@"test"]];}


I'm sure i did the calculation part wrong. i just cant grasp how to get each value to give a specific text output. I cant even find an example that fits what i'm trying to do here. Ive seen it done on an app so i know its entirely possible.

I doubt you are going to find an example that fits what you are trying to do, since what you trying to do is unique to your needs and interests.

Start by mapping out what you want to do.

Are you always converting 1 source unit to destination units?

Map out a table that shows all possible source unit values and all possible destination unit values. Calculate a conversion factor for each combination.

Since it looks like the number of combinations is fairly small, you could create a 2 dimensional array of floats that would store your conversion table values.

You'd then use code like this:

Code:
float conversion_factor = table[sourceUnit][destUnit];
result_value = 1 * conversion_factor;  //Convert 1 source unit to destination units.
 

johnnyfla123

macrumors newbie
Original poster
Jun 15, 2013
21
0
what my plan was to just make it so when you choose row 1 of component 1 and row 1 of component 2 you would get a text output that i would simply put the calculate and keep going in those combo's 1 2, 2 2, 1 3, etc.
 

Duncan C

macrumors 6502a
Jan 21, 2008
853
0
Northern Virginia
what my plan was to just make it so when you choose row 1 of component 1 and row 1 of component 2 you would get a text output that i would simply put the calculate and keep going in those combo's 1 2, 2 2, 1 3, etc.

"you would get a text output that i would simply put the calculate and keep going in those combo's 1 2, 2 2, 1 3, etc."

Sorry, that makes no sense.
 

johnnyfla123

macrumors newbie
Original poster
Jun 15, 2013
21
0
if you chose row 1 on component 1 and row 1 on compnent 2 it would give you a text output defined. if you chose row 2 of c1 and row 1 of c2 if would give you a different text output defined. if you choose row 1 of c1 and row 2 of c2 it would give you the same text output as row 2 of c1 and row 1 of c2.

c1 is component 1 and c2 is component 2. I thought doing this part would be the easiest lol
 

Duncan C

macrumors 6502a
Jan 21, 2008
853
0
Northern Virginia
if you chose row 1 on component 1 and row 1 on compnent 2 it would give you a text output defined. if you chose row 2 of c1 and row 1 of c2 if would give you a different text output defined. if you choose row 1 of c1 and row 2 of c2 it would give you the same text output as row 2 of c1 and row 1 of c2.

c1 is component 1 and c2 is component 2. I thought doing this part would be the easiest lol

So multiple C1 by 100 and add it to c2. Then have a big switch statement that assigns strings based on the resulting value

Code:
int switchValue = C1 * 100 + C2;

Code:
C1  C2   result
--   --    ------
0     0    0
0     1    1
0     2    2
1     0    100
1     1    101
1     2    102
...
3     0    300
3     1    301
 

johnnyfla123

macrumors newbie
Original poster
Jun 15, 2013
21
0
finally got it figured out. thank you again for your help i found it was simple then i though :)

Code:
    int sourceUnit = [pickerView selectedRowInComponent:0];
    int destUnit = [pickerView selectedRowInComponent:1];
    
    if(sourceUnit == 1 && destUnit == 1){[OutputLabel setText:[NSString stringWithFormat:@"test"]];}
 

Duncan C

macrumors 6502a
Jan 21, 2008
853
0
Northern Virginia
finally got it figured out. thank you again for your help i found it was simple then i though :)

Code:
    int sourceUnit = [pickerView selectedRowInComponent:0];
    int destUnit = [pickerView selectedRowInComponent:1];
    
    if(sourceUnit == 1 && destUnit == 1){[OutputLabel setText:[NSString stringWithFormat:@"test"]];}

Remember that the selected component numbers are zero-based, as are most things in C languages. If the first row in component is selected, you'll get a zero in sourceUnit, not a 1.
 

johnnyfla123

macrumors newbie
Original poster
Jun 15, 2013
21
0
i used this and it worked perfectly :)

Code:
if(sourceUnit == 0 && destUnit == 0){[OutputLabel setText:[NSString stringWithFormat:@""]];}
    else if (sourceUnit == 1 && destUnit == 1){[OutputLabel setText:[NSString stringWithFormat:@"1 Gram is equal to 1 Gram"]];}
 

Duncan C

macrumors 6502a
Jan 21, 2008
853
0
Northern Virginia
i used this and it worked perfectly :)

Code:
if(sourceUnit == 0 && destUnit == 0){[OutputLabel setText:[NSString stringWithFormat:@""]];}
    else if (sourceUnit == 1 && destUnit == 1){[OutputLabel setText:[NSString stringWithFormat:@"1 Gram is equal to 1 Gram"]];}

Do yourself and your readers a favor. Don't put your if statement, the brackets, and the code for the if statement all on one line. It makes the code very busy and hard to read. White space is your friend!

Isn't this much easier to follow?

Code:
if(sourceUnit == 0 && destUnit == 0)
{
  [OutputLabel setText:[NSString stringWithFormat:@""]];
}
else if (sourceUnit == 1 && destUnit == 1)
{
  [OutputLabel setText:[NSString stringWithFormat:@"1 Gram is equal to 1 Gram"]];
}

Also, there is no reason to use stringWithFormat when all you're passing in is a single string.

Code:
[OutputLabel setText:[NSString stringWithFormat:@"1 Gram is equal to 1 Gram"]];

Can and should be rewritten as

Code:
[OutputLabel setText: @"1 Gram is equal to 1 Gram"];
 

johnnyfla123

macrumors newbie
Original poster
Jun 15, 2013
21
0
Do yourself and your readers a favor. Don't put your if statement, the brackets, and the code for the if statement all on one line. It makes the code very busy and hard to read. White space is your friend!

Isn't this much easier to follow?

Code:
if(sourceUnit == 0 && destUnit == 0)
{
  [OutputLabel setText:[NSString stringWithFormat:@""]];
}
else if (sourceUnit == 1 && destUnit == 1)
{
  [OutputLabel setText:[NSString stringWithFormat:@"1 Gram is equal to 1 Gram"]];
}

Also, there is no reason to use stringWithFormat when all you're passing in is a single string.

Code:
[OutputLabel setText:[NSString stringWithFormat:@"1 Gram is equal to 1 Gram"]];

Can and should be rewritten as

Code:
[OutputLabel setText: @"1 Gram is equal to 1 Gram"];


thanks for the modification ill add it now :) i just kept it as is cause it worked and im happy with working lol
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.