0

Is this appropriate code for the arrays in a picker with two identical components? Or can both components somehow use the same arrays?

    - (void)viewDidLoad
{
    self.fromArray = [[NSArray alloc] initWithObjects:
                      @"Annual", @"Monthly", @"48/Year", @"SemiMonthly", @"BiWeekly", @"Weekly", @"Hourly", nil];

    self.fromValues = [[NSArray alloc] initWithObjects: 
                       [NSNumber numberWithFloat:1.0],
                       [NSNumber numberWithFloat:12.0], 
                       [NSNumber numberWithFloat:48.0],
                       [NSNumber numberWithFloat:24.0], 
                       [NSNumber numberWithFloat:26.0],
                       [NSNumber numberWithFloat:52.0], 
                       [NSNumber numberWithFloat:2080.0], nil];


    self.toArray = [[NSArray alloc] initWithObjects:
                      @"Annual", @"Monthly", @"48/Year", @"SemiMonthly", @"BiWeekly", @"Weekly", @"Hourly", nil];

    self.toValues = [[NSArray alloc] initWithObjects: 
                     [NSNumber numberWithFloat:1.0],
                     [NSNumber numberWithFloat:12.0], 
                     [NSNumber numberWithFloat:48.0],
                     [NSNumber numberWithFloat:24.0], 
                     [NSNumber numberWithFloat:26.0],
                     [NSNumber numberWithFloat:52.0], 
                     [NSNumber numberWithFloat:2080.0], nil];

Also, how would I properly format a calculation using values from both components and a Text Field? This is just not working.

I tried this, but I get undeclared identifier errors with the use of 'row'.

- (NSString *)pickerView:(UIPickerView *)pickerView
             titleForRow:(NSInteger)row
            forComponent:(NSInteger)component
{
    if (component == 0) {
        return [fromArray objectAtIndex:row];
    }
    return [toArray objectAtIndex:row];
} 
-(void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row
      inComponent:(NSInteger)component {
}

- (IBAction)Convert:(id)sender {
    float valuein = [[fromValues objectAtIndex:row] floatValue];
    float valueout = [[toValues objectAtIndex:row] floatValue];
    float input = [inputText.text floatValue];
    float result = input * valuein / valueout;
    NSString *resultString = [[NSString alloc] initWithFormat: @"$ %@", [toArray objectAtIndex:row]];
    resultText.text = [NSString stringWithFormat:@"$%6.2f",result];
}

EDIT: Here is the current version of full .m file code, as requested below. I suspect there is a bit of unnecessary code. The only warning is Unused variable 'resultString'.

#import "PayFrequencyViewController.h"

@interface PayFrequencyViewController ()

@end

@implementation PayFrequencyViewController
@synthesize payPicker;
@synthesize toArray;
@synthesize fromArray;
@synthesize toValues;
@synthesize fromValues;
@synthesize resultText;
@synthesize inputText;

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)viewDidLoad
{
    self.fromArray = [[NSArray alloc] initWithObjects:
                      @"Annual", @"Monthly", @"48/Year", @"SemiMonthly", @"BiWeekly", @"Weekly", @"Hourly", nil];

    self.fromValues = [[NSArray alloc] initWithObjects: 
                       [NSNumber numberWithFloat:1.0],
                       [NSNumber numberWithFloat:12.0], 
                       [NSNumber numberWithFloat:48.0],
                       [NSNumber numberWithFloat:24.0], 
                       [NSNumber numberWithFloat:26.0],
                       [NSNumber numberWithFloat:52.0], 
                       [NSNumber numberWithFloat:2080.0], nil];

    self.toArray = self.fromArray;
    self.toValues =  self.fromValues;

    [super viewDidLoad];
    inputText.keyboardType = UIKeyboardTypeDecimalPad;
}

- (void)viewDidUnload
{
    [super viewDidUnload];
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
    self.toArray = nil;
    self.fromArray = nil;
    self.resultText = nil;
    self.inputText = nil;
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return YES;
}

- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView {

    return 2;
}

- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component {

    if (component == 0) {
        return [fromArray count];
    }
    return [toArray count];
}

- (NSString *)pickerView:(UIPickerView *)pickerView
             titleForRow:(NSInteger)row
            forComponent:(NSInteger)component
{
    if (component == 0) {
        return [fromArray objectAtIndex:row];
    }
    return [toArray objectAtIndex:row];
} 

-(void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row
      inComponent:(NSInteger)component {
    _row = row;
}

- (IBAction)Convert:(id)sender {
//    float valuein = [[fromValues text] floatValue];
//    float valueout = [[toValues text] floatValue];
//    [resultText setText:[NSString stringWithFormat:@"%6.2f", result]];
//    [inputText resignFirstResponder]; 
    float valuein = [[fromValues objectAtIndex:_row] floatValue];
    float valueout = [[toValues objectAtIndex:_row] floatValue];
    float input = [inputText.text floatValue];
    float result = input * valuein / valueout;
    NSString *resultString = [[NSString alloc] initWithFormat: @"$ %@", [toArray objectAtIndex:_row]];
    resultText.text = [NSString stringWithFormat:@"$%6.2f",result];
}

- (IBAction)Clear:(id)sender {
    inputText.text = @"";
    resultText.text = @"";
}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event 
{
    [inputText resignFirstResponder];
}
@end
steveald
  • 23
  • 5

1 Answers1

0

OK, there are a few things :

First, your arrays are leaking memory, since you alloc, init them without releasing them (unless you use ARC, in that case this is fine).

Second, if you want them to share the same array, why don't you do something like

 self.toArray = self.fromArray;
 self.toValues =  self.fromValues;

?

how would I properly format a calculation using values from both components and a Text Field?

You need to be more clear here, I don't understand what you're trying to do.

However, in your first chunk of code : at the time you try to use row it isn't defined. You might need to learn about variables and scope.

Why don't you create an instance variable _row in your class @interface

NSInteger _row;

and set that variable like

-(void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row
  inComponent:(NSInteger)component {
      _row = row;
 }

ant then, use _row afterward when you need it ?

As for the last chunk of code, what were you trying to achieve with [fromValues text] ?

Olotiar
  • 3,225
  • 1
  • 18
  • 37
  • Thanks for the response. I'm using Xcode v.4.3.2, which no longer allows (or needs) releasing them. So, I think I'm good there. And I revised the arrays code as specified. So far, so good. (I assumed there was an easy way to do it. I just didn't know how.) – steveald Jul 30 '12 at 17:19
  • As for the calculation, I found samples to go by for doing a calculation from a single-component picker, but not from a two-component picker. I'll try the suggestions you made, unless you think I would be better off using a variation of the last bit of code I showed instead. I'm afraid the last bit is one instance where I found something that does something like what I want and modified it to work for me, only this time I got lost along the way. – steveald Jul 30 '12 at 17:31
  • I will help if needed, but more details will be required. Mark this answer as accepted if you have no further question. And finally, Xcode version has little to do with memory management, you might want to check that ARC is enabled in your project settings. – Olotiar Jul 30 '12 at 17:44
  • Thank you for the offer to help. I first started this request [here](http://stackoverflow.com/questions/11546164/how-to-code-calculations-in-xcode-using-2-component-picker-and-text-field-entry), but got nowhere - probably because I tried to cram too much information in there. – steveald Jul 30 '12 at 18:21
  • The bottom line is, I want the user to select options from each side of a 2-component picker, enter a number in a text field, and tap a button. When they do, the results of a calculation based on the number and the values from the two options selected will appear. I modified similar samples to work for me, but got lost in the process. I suspect I need to find more basic code that accomplishes the same thing without the parts that are unnecessary for my purposes. – steveald Jul 30 '12 at 18:23
  • Regarding ARC, according to a book I have on iOS 5 application development using Xcode as well as responses to the errors I was receiving, any project built with Xcode 4.2 or later automatically uses ARC and won't allow things like release, retain or dealloc. I just assumed that, if I knew it, it must be common knowledge. But I also realize the scope of this forum goes way beyond Xcode programming. – steveald Jul 30 '12 at 18:26
  • Regarding ARC : Starting from Xcode 4.2 and iOS 5, all projects have ARC enabled by default, but that default behaviour is not necessarily always wanted. AAnyhow, if `release` was throwing errors at you, you probably have ARC enabled. But don't just assume it's on because you are using the 5.0 SDK or Xcode 4.2+. Edit your question with your **full** new code (from the indication I gave you) and I will try guide you – Olotiar Jul 31 '12 at 07:41
  • I reposted the entirety of my .m file code as requested. The only warning is Unused variable 'resultString' in the IBAction(Convert) section. I suspect, though, that there is a bit of code that could be eliminated or streamlined. And I finally found where "Objective-C Automatic Reference Counting" was set to 'Yes'. I assume, for the sake of ease of use, I should leave it that way. Thank you for your help. – steveald Jul 31 '12 at 13:32
  • Ok, I see your code. It looks correct to me, what is not working ? – Olotiar Aug 01 '12 at 07:36
  • I've made the changes discussed above now. I also commented out the line under (IBAction)Convert that starts with: "NSString *resultString" since it gives an "unused variable" warning and looks like it's functionality was replaced by the next line anyway. – steveald Aug 01 '12 at 14:22
  • When I run the app, both components display the correct objects. But, when I enter a value in the "input" field and tap the "Convert" button, I get the same value back as the "result". That tells me the value from just one component is being used for the "valuein" and "valueout" portions of the calculation. Probably because I used code from a sample that did a calculation based on an input value and a single-component switcher. I'll set up a couple of text fields to display the values each side of the picker produces to confirm that, as well as determine which side is getting used for both. – steveald Aug 01 '12 at 14:22
  • Confirmed. "valuein" and "valueout" are both array values from the object selected in component 1 on the right. i.e., If Annual and Weekly are selected, the values should be 1.0 and 52.0; but both are going into the calculation as 52.0. So, they cancel each other out, leaving result equal to input. (result = input * valuein / valueout) – steveald Aug 01 '12 at 15:01
  • OK, My bad, I see the error now. Of course they are equal, because the arrays are equals and you pick the same element at `_row`. You have to create two variables `_rowTo` and `rowFrom` and check in `-(void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component` which component (you have the variable `component`) it is to update one of these two variables. – Olotiar Aug 01 '12 at 15:27
  • Eureka! I created the variables as you said and changed "_row = row;" to the following. And it works! { if (component == 0) { _rowTo = row; } else _rowFrom = row; } Thank you for your patience and help. Unless you see anything that can be eliminated or made more efficient (or needs a memory leak plugged), I'll run with it as is. Thanks again. – steveald Aug 01 '12 at 18:26