So I have this app that tracks your speed and altitude. I have a UILabel that shows the current speed you are at and the current altitude you are at. What I want to do is have a label that shows the max altitude and the max speed. So basically if you are running and your speed reaches 5 mph the max label will say 5 mph and then if you get to 6 mph the max label will change to 6 etc... Same thing for the altitude label. So how do I do this?
I'm assuming that you have either a float or an integer value for your currentSpeed/currentAltitude. Have another set of the same type, (I'll use int for my example) and name them maxSpeed/maxAltitude.
And add this code to the function which updates speed.
if(currentSpeed > maxSpeed){
maxSpeed = currentSpeed;
maxSpeedLabel.text = [NSString stringWithFormat: #"%d mph", maxSpeed];
}
Same goes with altitude.
EDIT: Given your statement: speedLabel.text = [NSString stringWithFormat:#"%.2f", [location speed]*2.236936284];
Here is the updated code:
float currentSpeed = [location speed] * 2.236936284;
if(currentSpeed - maxSpeed >= 0.01){
maxSpeed = currentSpeed;
maxSpeedLabel.text = [NSString stringWithFormat: #"%.2f mph", maxSpeed];
}
Also, now, currentSpeed and maxSpeed are both floats. Note that I have used a different type of comparison here. Since floats go into a great deal of precision (that we don't always need) I've restricted yours to 2 decimal places. So the text and maxSpeed will only update if it is greater by a factor of 0.01.
Related
I am working on a driver behavior app and I am using SOMotionDetector (Thanks to MIT). Its giving speed and Motion Type (Not Moving, Walking, Running, Automotive) of device. I will use Automotive in my case as I need to detect driver behavior. This is detecting Motion Type based on speed with some thresholds set for Walking, Running, Automotive or if available it uses M7 Chip. It updates location approximately after every second (time varies based on GPS) in [SOMotionDetector sharedInstance].locationChangedBlock To detect Aggressive speed or break I am checking is that the increase/decrease of speed in last second. If it increases from a certain threshold (I am using kAggressiveSpeedIncrementFactor 8.0f) then its aggressively increasing speed, and if there is decreasing speed (difference factor is negative in this case) then its aggressive break. For turn I am playing with angle of latitude and longitude points, following is code for my logic:
#define kAggressiveSpeedIncrementFactor 8.0f // if 8 km/h speed was increased in last second
#define kAggressiveAngleIncrementFactor 30.0f // 30 degree turn angle
#define kAggressiveTurnIncrementFactor 5.0f . // while turn the increasing speed factor in last second
SOMotionDetector *motionDetector = [SOMotionDetector sharedInstance];
motionDetector.locationChangedBlock = ^(CLLocation *location) {
if (motionDetector.motionType == MotionTypeAutomotive) {
SOLocationManager *locationManager = [SOLocationManager sharedInstance];
float currSpeed = motionDetector.currentSpeed * 3.6f;
float lastSpeed = motionDetector.lastSpeed * 3.6f;
float currAngle = locationManager.currAngle;
float lastAngle = locationManager.lastAngle;
self.speedDiff = currSpeed-lastSpeed;
self.angleDiff = currAngle-lastAngle;
if (fabs(self.speedDiff)>kAggressiveSpeedIncrementFactor && fabs(self.angleDiff)<kAggressiveAngleIncrementFactor) {
NSString *msg = #"Aggressive Speed";
if (self.speedDiff < 0)
msg = #"Aggressive Break";
NSLog(#"%#", msg);
}
if (fabs(self.angleDiff)>kAggressiveAngleIncrementFactor && currSpeed>kAggressiveTurnIncrementFactor) {
NSLog(#"aggressive turn");
}
}
};
I have created currentSpeed and lastSpeed in SOMotionDetector class (for my speed difference) and currAngle and lastAngle in SOLocationManager. Please have a look at code,
Aggressive Speed some times work perfect
My question is:
Is this right approach what I am doing?
For detecting aggressive turn with the angle some times this happens that if
my vehicle is going 50 degrees angle (calculated with current and last lat, longs) on a strait road, some times the GPS detect location right or left side of road that give a big difference to the angle (like the path becomes a zig zag). any suggestion for this?
I'm adding a bunch of coordinates into quad tree and when I'm asking for the closest coordinate near my location, sometimes I've coordinate with 0 at the end, added automatically perhaps by the quad tree or I don't know how.
The problem is when I'm asking the double value in my core data using predicate it won't match because of the 0 digit addition to the number.
I thought about removing it when I've 0 but I'm sure there is a better way doing it.
For example:
Near location 31.123456, 34.123456, the nearest is 31.123444, 34.123450
when '34.123450' is actually 34.12345 in the database.
//Convert float to String
NSString *str_lat = #"34.123450";
NSString *trimmedString=[str_lat substringFromIndex:MAX((int)[str_lat length]-1, 0)];
if([trimmedString isEqualToString:#"0"])
{
str_lat = [str_lat substringToIndex:[str_lat length] - 1];
}
else
{
}
NSLog(#"%#",str_lat);
First: You should not store numbers as strings. 7.3 and 7.30 are the same values with simply different representations. You should not compare the representations, but the value.
Second: You should not compare floating-point numbers with == but their difference to a delta. In a calculation precision might get lost, rounding is applied and so on. The "mathematical" equal values might be physical different by a more or less small amount.
// remove the zeros from values (if you have them as floats)
NSString *valueFromTheDataBase = [NSString stringWithFormat:#"%g", 34.123450];
NSString *yourValue = [NSString stringWithFormat:#"%g", 34.12345];
if([yourValue isEqualToString:valueFromDataBase]) {
// they are equal
}
OR Make Them floats and compare them
// make them floats and compare them
CGFloat floatFromDB = [valueFromDB floatValue];
CGFloat yourFloat = [yourString floatValue];
if((floatFromDB - yourFloat) == 0) {
// they are equal
}
UPDATED as #Amin Negm says
In UISlider Control if I set "MinimumValue = 0" & "MaximimValue=2000" then I am not able to set the exact value. On release of slider thumb image it changes the value to + or - 5 to10. My slider width = 225px.
For example:- if I try to set the slider value to 100 then on release of slider thumb it shows me result like 105 or 95.
Code
IBOutlet UISlider * slider;
//"Slider" Object attached using XIB(.NIB)
slider.minimumValue = 0;
slider.maximumValue = 100;
//Attached Below Method Using XIB(.NIB) with "value Changed" event.
-(IBAction)slider_Change:(id)sender;
{
//Assigning value to UITextField
textFiled.text = [NSString stringWithFormat:#"%d",(((int) (slider.value)) * 20)];
}
Because you have set your slider range to be so large each pixel on the screen is equivalent to 8.888.
2000 / 255 = 8.8888888889
To get graduations of 1 you'll need to move the slider 1/8 of a pixel (this is impossible).
Alternatives are:
Make the slider longer
Reduce the slider range
Use a different control UIStepper
In addition to the answer by #rjstelling, it seems as if you are trying to convert the value of the slider to become an integer value. I believe that the default of the slider is a double value, this would cause the value to become rounded as it is increasing, since there will not be decimal values. Unless it is a requirement, see if you can use double.
textFiled.text = [NSString stringWithFormat:#"%f",(slider.value * 20.0)];
or if for some reason you'd want to restrict the level of decimal places you could go, you could do:
textField.text = [NSString stringWithFormat:#"%.1f", slider.value * 20.0];
This will give you the result of a decimal like 1.5 as your answer.
You could do anything with the decimal or even do something like %1.2f, %4.3f, or even %10.4f,
those will produce results like: 0.34, 0012.446, and something extreme like 000000345.1111
Hope this helps
Is there a good way to reverse UISlider values? The default is min on the left and max on the right. I'd like it to work the opposite way.
Rotating it 180 degrees seems a bit silly. Any ideas?
Thanks!
Just subtract the value you get from the slider from the maximum value, that will reverse the values.
I then needed the exact same thing as you...so rotated it another 90 degrees placing it in an upside down position. Slider is symetrical, so it looks exactly the same in both positions. But the min and max values are now the opposite.
Command is...
mySlider.transform = CGAffineTransformRotate(mySlider.transform, 180.0/180*M_PI);
you can use the following formula:
let sliderValue = yourSlider.minimumValue + yourSlider.maximumValue - yourSlider.value
Will reverse your values.
Subclass NSSlider/UISlider. Override these two methods thus -
//Assumes minValue not necessarily 0.0
-(double)doubleValue
{
double minVal = [self minValue];
double maxVal = [self maxValue];
double curValue = [super doubleValue];
double reverseVal = maxVal - curValue + minVal;
return reverseVal;
}
-(void)setDoubleValue:(double)aDouble
{
double minVal = [self minValue];
double maxVal = [self maxValue];
double reverseVal = maxVal - aDouble + minVal;
[super setDoubleValue:reverseVal];
}
This will invert the values allowing right/top to appear as minimum and left/bottom to appear as maximum
The accepted answer is incorrect because it assumes that the slider's Min value is 0.
In my case, my Min is 1.1 and Max is 8.0
You need to subtract the slider's value from Min+Max value to inverse the value.
Try this beautiful line -
yourSlider.semanticContentAttribute = .forceRightToLeft
This changes the min-max track colors + invert the values + you are not losing your frame like in the transform answers.
Just subtract slider current value from max value.
label.text = [NSString stringWithFormat:#" %.f%% ", 100 - self.slider.value];
You can simply flip the slider horizontally using transform (Swift 5.0):
slider.transform = CGAffineTransform(scaleX: -1, y: 1);
How about this:
slider.maximumValue = -minimumValue;
slider.minimumValue = -maximumValue;
-(void) sliderChanged:(UISlider *) slider {
float value = -slider.value;
// do something with value
}
Then just use -slider.value.
I'm dealing with an NSMutableArray of NSNumber and I ran into a weird bug. The [NSNumber doubleValue] (construct with double 0) seems to not to be equals to 0.0.
The bug appears in the simpliest function ever : the max function.
- (double) maxValY{
double max = DBL_MIN;
for (NSNumber *doubleNumber in arrayNumbers) {
if (max<[doubleNumber doubleValue]){
max = [doubleNumber doubleValue];
}
}
NSLog(#"max %f",max);
if(max <=0.0){
NSLog(#"max is equal to 0");
return 1;
}else{
NSLog(#"max is not equal to 0");
}
return max;
}
The console prints :
2013-01-02 11:27:56.208 myApp[1920:c07] max 0.000000
2013-01-02 11:27:56.210 myApp[1920:c07] max is not equal to 0
This isn't a bug: it's double precision. With floating point number what you see is not necessarily what you're getting. This question has some more information:
Why do I see a double variable initialized to some value like 21.4 as 21.399999618530273?
The easiest solution is going to be to cast to an integer, if all you care about is whether a number is equal or greater than zero. There are other alternatives that are more complex: the answer I've linked to has a few. The link someone gave you in the comments about floating point mathematics may also be helpful.