Couple Obj C issues including an error - iphone

So basically in this code I placed below there is a couple things I would like to accomplish. 1) In that first one I would like the Text Field to close after done is pressed, but it is not doing so. (Found that code on other forums). 2)On that first button when it is pressed down I would like it to send a time to be saved for when the button is released. 3) On release of that button I would like it to calculate the time between the two times along with some other calculations later.
Problem that I am mainly getting here is the error from the NSTimeInterval. It keeps telling me that NSTimeInterval is incompatiable with type NSTimeInterval. So a double is incompatible with a double??? (I have also tried it with NSTimeInterval *timePassed in the .h and just trying to set timePassed = to it and it doesn't work either. Similar error happens.
#import "MphViewController.h"
#implementation MphViewController
#synthesize speed, distance;
- (BOOL)textFieldShouldReturn:(UITextField *)textField{
[textField resignFirstResponder];
return YES;
}
-(IBAction)triggerDown:(id)sender{
timeStart = [NSDate date];
}
-(IBAction)triggerUp:(id)sender{
NSInteger *dist;
NSString *display;
NSTimeInterval *timePassed = [timeStart timeIntervalSinceNow];
if ([distance.text length]== 0) {
display = #"Please enter a distance";
}
else{
dist = atoi(distance.text);
display = [[NSString alloc] initWithFormat:#"%d MPH",dist];
}
speed.text = display;
[display release];
}
Also if you have a chance to glance at the else statement. I'm not sure if that will work (seeing is after I enter a distance I still cant get rid of the numberpad). Id like to pass mph once it is calculated into that to be displayed on the screen. Very confused with how parsing is done on obj c. Anyways thanks for any and all help.
As for the textField part. My textField that it is assigned to is distance. Should that Bool be written differently to have distance in it or is that just the way it is supposed to be written?

You are denoting primitive types as pointers where they do not need to be. Remove the star (*) from the NSInteger and NSTimerIntervaldeclaration. The if check looks fine but instead of atoi just use:
dist = [distance.text integerValue];
Edit:
Notice a couple of memory management issues.
1 . Make sure you properly retain/release the date then later release it in dealloc.
-(IBAction)triggerDown:(id)sender{
[timeStart release];
timeStart = [[NSDate alloc] init];
}
2 . Your if statement will result in trying to release an NSString literal which likely will not crash but is incorrect memory management. Just use an autoreleased string and remove the [display release];
...
else{
dist = [distance.text integerValue];
display = [NSString stringWithFormat:#"%d MPH",dist];
}
speed.text = display;
}

Related

label not updating in setter

ok so this problem is kinda weird because the NSLog I have right in front of the line of code that should be printing out the text is returning the correct value.
Here's the code:
-(void)setCurrentDate:(UILabel *)currentDate
{
NSInteger onDay = 1; //because if it's today, you are on day one, not zero... no such thing as a day zero
//get the nubmer of days left
if( [[NSUserDefaults standardUserDefaults] objectForKey:#"StartDate"] ){ //if there is something at the userdefaults
onDay = [self daysToDate:[NSDate date]];
}//otherwise, onDay will just be one
self.theCurrentNumberOfDaysSinceStart = onDay;
NSLog(#"On day: %d", onDay); //this is returning the correct values....
//print it out on the label
[currentDate setText:[NSString stringWithFormat:#"On day: %d", onDay]];//echoes out the current day number
}
So when the app first launches, everything is fine. The label updates and everything. The problem arises when I hit a button that basically grabs a new date. In the process, it runs this:
//need to reload the "on day" label now
[self setCurrentDate:self.currentDate];
//and the "days left" label
[self setDaysLeft:self.daysLeft];
Again, I'm thinking this should all be correct because the NSLog is returning the correct stuff. I'm thinking that the problem is with the last line in the first block of code I showed... the line with the setText.
thanks for all your help!
cheers,
Matt
If you used a nib
When the nib loads and establishes all of it connections it... (From the Resource Programming guide)
looks for a method of the form set OutletName: and calls it if such a method is present
Therefore the nib will load and call setCurrentDate: passing in the unarchived UILabel as the parameter
In your method you configure the UILabel using the local reference passed into the method
[currentDate setText:[NSString stringWithFormat:#"On day: %d", onDay]];
You at no point actually store a reference to this UILabel in an ivar, so technically you have leaked the label and as you have not set the ivar currentDate it will be initialised to nil. This is the danger of overriding a setter with an incorrect implementation.
At some point in your method you should be setting your ivar to the passed in variable. A normal setter would look like this
- (void)setCurrentDate:(UILabel *)currentDate;
{
if (_currentDate != currentDate) {
[_currentDate release];
_currentDate = [currentDate retain];
}
}
But
In your example I would not worry about this at all I would instead change this
//need to reload the "on day" label now
[self setCurrentDate:self.currentDate];
to something like
[self updateCurrentDate];
The implementation would look something like:
- (void)updateCurrentDate;
{
NSInteger onDay = 1;
if ([[NSUserDefaults standardUserDefaults] objectForKey:#"StartDate"]) {
onDay = [self daysToDate:[NSDate date]];
}
self.theCurrentNumberOfDaysSinceStart = onDay;
[self.currentDate setText:[NSString stringWithFormat:#"On day: %d", onDay]];
}

Updating label based on picker value the very first time a view is loaded

I'm new to iPhone development, so my apologies if this is a ridiculous question.
I'm following a sample from a book where it creates a exchange rate UIPicker and when you select one of the entries, it displays the conversion of US dollars into whatever currency is picked.
I want the value to be updated in my label before I start changing the value from the picker.
The very first time i enter my US dollar value in the textbox and I click on the "Return" button, i want the label to update and displays its equivalent value in whatever currency is currently selected in the picker.
I have the correct code in the didSelectRow event, and that part works as long as i start spinning the picker's component wheels, so I thought I'd take that code and put it in a function which would have one parameter i.e. row and this function would then be called from didSelectRow where the row parameter would be passed and then I would:
This is the code from the didSelectRow:
float rate = [[exchangeRates objectAtIndex:row] floatValue];
float dollars = [dollarText.text floatValue];
float result = dollars * rate;
NSString *resultString = [[NSString alloc] initWithFormat:#"%.2f USD = %.2f %#", dollars, result, [countryNames objectAtIndex:row]];
resultLabel.text = resultString;
[resultString release];
Call this function when the "Did End on Exit" event for the textbox but my I'm having two problems:
What is the correct way to write the function. Whatever way I write the function, I get various errors/warnings
How do i get the currently select row of the picker, so that I can pass it to this function when the "Did End on Exit" event occurs when i click on the "Return" button.
Thanks
T.
I am not sure, I completely understood you what exactly you are trying to do here. but still I am going ahead what you can do here is:
first of all declare an class variable of type int which will store the row index whenever didSelectRow delegate method will be called, mean time create a method like:
-(void)updateLabel:(int) rowIndex
{
float rate = [[exchangeRates objectAtIndex:row] floatValue];
float dollars = [dollarText.text floatValue];
float result = dollars * rate;
NSString *resultString = [[NSString alloc] initWithFormat:#"%.2f USD = %.2f %#", dollars, result, [countryNames objectAtIndex:rowIndex]]; // here it will go rowIndex which is the row value you stored in your variable
resultLabel.text = resultString;
[resultString release];
}
and call this method when you hit return.
I hope this helps you.
~Manoj

Accessing a UITextField from an array in Objective-C

I have 4 UITextFields that I'm dynamically creating, in the viewDidLoad, which works good. I want to reference those objects when the UISlider value changes. Right now I'm storing those objects in a NSMutableArray and accessing them like so from the sliderChanged method:
NSInteger labelIndex = [newText intValue];
labelIndex--;
NSUInteger firstValue = (int)0;
NSMutableArray *holeArray = [pointsArray objectAtIndex:labelIndex];
UITextField *textField = [textFieldArray objectAtIndex:firstValue];
NSString *newLabel1Text = [[NSString alloc] initWithString:[[holeArray objectAtIndex:firstValue] stringValue]];
[textField setText: newLabel1Text];
[newLabel1Text release];
Everything is working good, but the program crashes on the setText: method. The last message I get from the program is: [UILabel drawTextInRect:] and then I get a EXC_BAD_ACCESS failure.
I want to be able to acces that dynamically created UITextField, but I must be going about it the wrong way.
Thanks!
Uh, yea, you create a text field, but you aren't displaying the field itself, just creating it.
If you want to do what I think you want to do, I would just do if statements.
ex.
if (firstValue == 1)
{
fieldone.text = #"whatever";
}
else if (firstValue == 2)
{
fieldtwo.text = #"whatever";
}

Simple iPhone tally method question

Just trying to create a simple method that counts up 1 on the tally when the button is pressed. My knowledge is extremely limited and I am pretty sure that my problem is somewhere in the method implementation:
-(IBAction) updateTally:(id) sender {
NSString *text;
int total = 0;
total = total + 1;
text=[[NSString alloc] initWithFormat: #"%i", total];
lblTally.text = text;
}
I have done the necessary interface declarations for the lblTally UILabel and the updateTally method. I suspect that there is some sort of an NSString/int/%i/%# mixup that I am making but I'm not sure how to fix it. When I run the program as it currently is it displays a 0 in the lblTally label field on the iphone. When I press the button it then displays a 1 in that field. However, if I continue to press the button - nothing happens, it just remains a 1. How do I make it count up as I continually press the button over and over?
The problem is that you are reinitializing the total in each updateTally. You need to either store the tally in a member variable or extract the existing tally from the string, update it, then write it back to the string.
- (IBAction) updateTally:(id) sender
{
int oldtally = [lblTally.text integerValue];
int newtally = oldtally + 1;
lblTally.text = [NSString stringWithFormat:"%d",newtally];
}
I should also point out that your current code has a memory leak (you invoke alloc/init, but then you don't invoke release after you have assigned the result to the lblTally.text variable). You should either invoke [text release] after lblTally.text = text, or you should use stringWithFormat like I have used above, which uses autorelease so that the string does not need to be explicitly released (since it will be automatically released).
You are re-initialising the total variable each time the method runs.
int total = 0;
Move than line of code outside of the method. I dont do apple development but it'll be something like:
int total = 0;
-(IBAction) updateTally:(id) sender {
NSString *text;
total = total + 1;
text=[[NSString alloc] initWithFormat: #"%i", total];
lblTally.text = text;
}

Why does my program crash when given negative values?

Alright, I am very confused, so I hope you friends can help me out. I'm working on a project using Cocos2D, the most recent version (.99 RC 1). I make some player objects and some buttons to change the object's life. But the weird thing is, the code crashes when I try to change their life by -5. Or any negative value for that matter, besides -1.
Straight forward, but when the NSnumber is -5, it doesn't even get called, it crashes at the NSlog statement. So... what's up with that?
Solved it by retaining the variable better. Thank you!
OK. I will say this again. Accessors are your friends. Use them. Always. NOTE: Yes I know Apple recommends not using them in init and dealloc but in 15 years, this has NEVER once caused an issue for me and NOT using them has. As in this case. There are times when you do NOT want to use them, but those times are much less than the times you DO want to use them.)
In your buttonText method:
- (void)buttonText:(int)number
{
lifeChange = [NSNumber numberWithInt:number];
NSString *text = [[NSString alloc] initWithFormat:#"%d", number];
CCLabel *label = [CCLabel labelWithString:text fontName:#"Times New Roman" fontSize:20];
label.position = CGPointMake(35, 20);
[self addChild:label];
}
You should be doing a:
- (void)buttonText:(int)number
{
NSString *text = [[[NSString alloc] initWithFormat:#"%d", number] autorelease];
CCLabel *label = [CCLabel labelWithString:text fontName:#"Times New Roman" fontSize:20];
[self setLifeChange:[NSNumber numberWithInt:number]];
label.position = CGPointMake(35, 20);
[self addChild:label];
}
Take a look at your code and understand how alloc/copy/retain need balanced with release/autorelease. At first glance, you are really messing up on the memory management.
Well, part of your problem is that you are not using the notation "self.lifeChange" anywhere which means that the NSNumber objects you assign to the lifeChange property are never retained. This means the NSNumber object may die at random.
Change to self.lifeChange and see if that helps.