Objective-C iOS, set a delay for an update of text - objective-c

I'm trying to find a solution to a problem I just stumbled upon.
Tried to search for it but it's not that I'm looking for.
I'm doing a GPS-app with two tabbars. I track the distance in the map-view (using CLLocation) and when I change tab to a different view the stringtext that say what distance it is from when I started don't update immediately, it take a couple of seconds.
And when I press the stop button I want it to either wait those couple of seconds so the real distance updates. But I dont want to freeze the app.
(*NSDate future = [NSDate dateWithTimeIntervalSinceNow: 3.0 ];
[NSThread sleepUntilDate:future];)
I'm saving the string with the distance in a cell in the second tab, so if I multitask while the app is going I want to just start the app and press stop. And then the new distance will be correct and saved. Hope I didn't confuse you with this much text I hope you understand what I asking for!
thx

[label performSelector:#selector(setText:) withObject:newText afterDelay:3.0];

So what you want to do is use dispatch_after:
dispatch_after(3 seconds, dispatch_get_main_queue(), ^
{
myLabel.text = <the value you want to appear>;
} );

Related

Obj-C Text fields, float values and SIGBART

I am writing an iOS application for (among many features) calculating alcohol content from sugar before and after fermentation for homebrewers. Now the problem is; every time I run my app in the simulator, it crashes with "Thread 1: Signal SIGBART" once I enter the UIViewController with the text fields, labels and buttons used in this function (in the implementation):
- (IBAction)calcAlc:(id)sender {
double ogVal = [[oGtext text]floatValue];
double fgVal = [[fGtext text]floatValue];
double alcoContent = ((1.05*(ogVal-fgVal))/fgVal)/0.79;
NSString *theResult = [NSString stringWithFormat:#"%1.2f",alcoContent];
alcContent.text = theResult;
}
I'm really stuck here -- any help is very appreciated. Thanks in advance!
You should check if fgVal is ever 0, since you are dividing by fgVal.
You will also want to use doubleValue instead of floatValue, since you are declaring them as double.
I think you should try float in place of double.
Now put break points on each and every method and debug it to get the exact point where you application is getting crashed and then you will be able to find the solution.
Also be sure to connect each and every ib outlet and action in your storyboard or nib(whatever you are using).
Please notify if it works..:)

Using NSTableView for logging?

I've been trying to work out how to use table views and I'm a little stuck if I'm honest. I wanted to use a tableview with a limited number of rows (say 50 max). It starts of empty, with 0 rows. Then I wanted to do something along the lines of:
[self logMessage:#"Waiting for response"];
Which inserts a new row at the bottom with the above text. If I do another call to this pseudo function:
[self logMessage:#"Server response received"];
It should insert yet another new row below the previous row, and ensure it is visible. Once the above limit of 50 is reached, and a new message is inserted, I wanted the oldest message to be removed. All of this would be scrollable, with the latest being visible by default.
Am I looking at the right thing to do this? Eventually, I was hoping to have this in a nice little drawer below the main window, which I can then toggle from the main menu if needed. But as I said, I can't work out how to use a table view properly, it doesn't seem to be as straight forward as other objects are.
Any example code would be greatly appreciated!
Since log viewer is a read-only application of a UITableView, the way you do it is rather straightforward once you understand the basics. Recall that table views rely on their data models to provide them with the correct information that needs to be displayed.
A data model for "the last fifty lines of log" could be as simple as an NSMutableArray: use insertObject:atIndex: to add lines, and removeLastObject to remove the "overflow" lines, like this:
NSMutableArray *logLines = [NSMutableArray array]; // <<== this goes into the init method
-(void) addLogLine:(NSString*)line {
[logLines insertObject:line atIndex:0];
while (logLines.count > 50) {
[logLines removeLastObject];
}
}
Now you can use logLines as your table's "model": the data provider can tell how many lines there are by looking at logLines.count; the content of each row in the table will be the object at the corresponding index in logLines, and so on. Take a look at the UITableView section of your favorite iOs tutorial for the "boilerplate code" that needs to be written in order to display array elements in a UITableView.

Adjust a "for" loops duration

I'm currently working on an app that will show a label that will start at zero, and count up to a number I specify. I wanted to do this using a simple loop like this one.
for (counterInt = 0; counterInt < 10; counterInt++)
{
NSLog(#"%i",counterInt);
}
The problem is, that this loop executes in less time than it takes for the view to appear on screen. My console logs 1-9 before the view finally loads with the label with showing 9. I've been researching for several hours trying to find a way to specify a duration for the loop and I can't seem to find any thing on this.
So my overall question is, is it possible to specify how long the loop should take to execute? If so, if anyone can point me in the right direction here it would be greatly appreciated!
Even if you slowed down the loop, it still wouldn't work. UI elements are only updated at the end of the run loop. You need to set up a timer and update the label in the method fired by the timer.
You're using the wrong approach. Try an NSTimer.
[NSTimer scheduledTimerWithTimeInterval:5.0
target:self
selector:#selector(incrementLabel:)
userInfo:nil
repeats:YES];
Then create a method called incrementLabel and have it increment an instance variable and update the label accordingly.
You can sleep a thread:
[NSThread sleepForTimeInterval:1];
However, jrturton and james supply the correct approach. I would place James' code in the viewDidAppear method so your label starts where you want it and the counter begins when the view appears.

indexpath as parameters

I got an table which is filled with VM's and i have 2 variable of the datatype NSIndexPath called:
selectedindexpath(the row the user clicks on) and
selectedindexpathFortheVMtoTurnOn(so it knows which row to reload when the VM went on);
which is both made in the .h as #paramters(retain) ..
i got a function that turns on the VM's and a function that CHECKS every 1 sec with a NSTimer if the guest is finally on then it reloads the row of selectedindexpathFortheVMtoTurnOn
im doing the same for OFF/REBOOT but i have got a problem with this.. im not able to request an action for more then 1 VM.. because it is overwriting the selectedindexpathFortheVMtoTurnOn value with the last row which i sent an action to and by doing so the table responds wierd and the app crashes..
so thats why i want to give the indexpath.row value as parameters with the NSTimer to the function that checks every 1 sec i have tried a few things but none have worked.. below the code of how i am giving the parameters
timertocallguest=[NSTimer scheduledTimerWithTimeInterval:1
target:self
selector:#selector(gettheguestyouaskedforTOTURNON:)
userInfo:selectedindexpathFortheVMtoTurnOn
repeats:YES];
and the function:
-(void)gettheguestyouaskedforTOTURNON:(NSIndexPath *)therow
and when i try to do a NSLog("%d",therow.row); it crashes...
and with NSLog("%d",therow); i get a whole diffrent value of the selectedindexpathFortheVMtoTurnOn that it used to had..
what am i doing wrong.?
sorry if its a wall of text. but i realy need to fix this problem as this is getting released as BETA nextweek in the appstore for the company where my traineeperiode is.
ty in advance.
EDIT:
i will try to show it with pictures this time.
At first im at the view with VM's
http://imageshack.us/photo/my-images/194/schermafbeelding2011052l.png/
after that i can press on the button with the arrow and i get to choose what i want to do.
http://imageshack.us/photo/my-images/822/schermafbeelding2011052r.png/
an activity indicator appears and it stops when the action is done.(which has to do with the NStimer that checks every 1 sec)
http://imageshack.us/photo/my-images/828/schermafbeelding2011052y.png/
http://imageshack.us/photo/my-images/811/schermafbeelding2011052t.png/
but when i try to do an action at 2 or more VM's the activity indicator on the last row i selected spins *x faster(depends on how manny actions i send.. 2 actions means it spins 2 times faster..(so weird)
.. i hope this is enough for you to understand what i mean now =)
The method triggered by an NSTimer object always has the timer as the argument. You can get the row like this.
-(void)gettheguestyouaskedforTOTURNON:(NSTimer *)timer {
NSIndexPath *indexPath = (NSIndexPath*)[timer userInfo];
NSLog(#"%d", indexPath.row);
}

How do I make a button play sounds in a certain order using an array?

I'm coding in Objective-C for the iPhone and I am trying create an array that plays a series of sounds. For example the first time I press the button I want it play sound "0.wav", but the second time I want it to play "1.wav", then "2.wav", "3.wav", etc. Then when I've played a total of 14 sounds (up to "13.wav") I want the loop to start over playing with 0.wav. I've looked around Google and the Apple development documentation for almost 4 days without much luck. So if someone could help me generate a code for this that would be greatly appreciated and if you wouldn't mind could you attempt to explain the code briefly so that I can learn what each part does.
Thank you, Joey
EDIT
Okay I've gotten the Array part down (thanks to Thomas) however neither of us are sure how to implement the soundID from the array to the action where I play the sound and how to play that sound. I used the format Thomas used for his array below if that helps you with your answer.
Thanks, Joey
First, create the array of your different sounds and a variable to hold the current index:
NSArray *sounds = [[NSArray alloc] initWithObjects:#"0.wav", #"1.wav", nil]; // add all your files here
NSUInteger currentSound = 0;
Then, when you handle your button tapped event, go to the next sound, and play it. If it's at the end of your NSArray, go back to index 0:
currentSound++;
if (currentSound >= [sounds count]) {
currentSound = 0;
}
// play the sound. Just call your own method here
[self playSoundWithFilename:[sounds objectAtIndex:currentSound]];