Display a signed float in UILabel - ios

I know there's a "hard" way to do that (not that hard, but not straight up).
I display a float value as a percentage in a label that way :
myLabel.text = [NSString stringWithFormat:#"%.1f%%", myFloat];
I want to force the label to display the sign of the float. Of course, it automatically shows the "-" if the value is negative. I know I can do that using a method of that type :
-(NSString *) stringFromFloat: (float) theFloat {
if (theFloat > 0) return [NSString stringWithFormat: #"+%.1f%%", theFloat];
else return [NSString stringWithFormat: #"%.1f%%", theFloat];
}
But that would imply calling [self stringFromFloat:aFloat]; every time I need to display the float value. I know using this solution is "better" because it lowers the number of re-used lines, but if my labels don't all show the same number of decimals, the stringFromFloat: may grow fast...
So my question is : is there an "easy" and standard way of doing this ? Like an NSString formatter or something ? For example, replacing #"%.1f%%" with something like #"%sign%.1f%%" ?
If there's nothing that straight, is something like stringFromFloat: the best solution ?
Thanks !

You do not need to make the sign part of the format - it can be parameterized, like this:
myLabel.text = [NSString stringWithFormat:#"%#%.1f%%", myFloat<0 ? #"" : #"+", myFloat];
Even if you want to put it in the format, the format string can be prepared in an expression:
myLabel.text = [NSString stringWithFormat:myFloat<0 ? #"%.1f%%" : #"+%.1f%%", myFloat];

Related

How to set maximum length for UILabel?

In Objective-C, I am attempting to set a limit of character length for a UILabel, but I could not find a way anywhere. For example, a line of text is entered into the UILabel, say 100, but if the maximum character length is set to 50, I just want it to cut off at 50 exactly and not even truncate. I just would like for it to cut off once it hits the limit.
I have tried this; but it didn't work:
NSString *string = my_uilabelText;
if ([string length] >74) {
string = [string substringToIndex:74];
}
Any insight or help would be greatly appreciated. Thank you
Based on your comment, what you actually implemented would work. You just have to ensure your syntax is correct.
Assuming your getting a string from a database:
NSString *string = stringFromDatabase;
//execute your conditional if statement
if (string.length > 50) { //meaning 51+
/* trim the string. Its important to note that substringToIndex returns a
new string containing the characters of the receiver up to, but not
including, the one at a given index. In other words, it goes up to 50,
but not 50, so that means we have to do desired number + 1.
Additionally, this method includes counting white-spaces */
string = [string substringToIndex:51];
}
Then we must set the labels text, this doesn't happen autonomously. So completely:
NSString *string = stringFromDatabase;
if (string.length > 50) {
string = [string substringToIndex:51];
}
self.someUILabel.text = string;
I think the way you are doing it is probably not user friendly. You're getting the string of a UILabel that already has text set and then resetting it. Instead, you should set the desired text to the UILabel before it is called by the delegate

Convert Double to NSString for label text

I'm trying to get an NSNumber out of an NSMutableArray that's been previously manipluated as a double and then added to the array to print out in a label (NSString).
It's important that the number stays as an accurate representatoin of a double with no scientific notation to abbreviate the answer.
The other requirement is to have it print to maybe 15 or 16 decimal places, rounding is optional but not required.
I also do not want trailing 0's when displaying the double
I've tried the following but these do not work...
This is ok but ends the number with a . (eg: 1+1=2.)
double test = [[data.argOperands objectAtIndex:0]doubleValue];
label.text = [NSString stringWithFormat:#"%3.2f", test];
label.text = [label.text stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:[NSString stringWithFormat:#"0"]]];
I then try something like this, which is wrong because if I do 9^99 it'll print inf or 0.0003/4 it'll give scientific numbers instead of the value
float y = [[calcData.argOperands objectAtIndex:0]doubleValue];;
label.text = [NSString stringWithFormat:#"%g", y];
If I do the following using double it's getting close, 9^99 works, but 3.33/5 returns 0.666000 with trailing 0's
double y = [[data.argOperands objectAtIndex:0]doubleValue];
label.text = [NSString stringWithFormat:#"%f", y];
Any code examples of how to do it this way using either NSNumberFormatter or NSDecimalNumber would be greatly appreciated.
"%.13f" Would give you 13 decimal places, but that would give you trailing zeros.
You may need to create an NSNumberFormatter and use that.
I suspect you're not going to be happy no matter what. Binary floating point is not an exact representation of decimal. The decimal value .1 is not an exact value in binary, and might display as something like .09999999998 if you display it with 13 decimal places.
You also might look at using NSDecimalNumber, which stores values as decimal digits. It's slower than other ways of doing math but you can control the results exactly.
After looking over http://nshipster.com/nsformatter/ and the giant NSNumberFormatter_Class doc I've come up with this code that prints everything to my requirements:
NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init];
[numberFormatter setUsesSignificantDigits: YES];
numberFormatter.maximumSignificantDigits = 100;
[numberFormatter setGroupingSeparator:#""];
[numberFormatter setNumberStyle:NSNumberFormatterDecimalStyle];
label.text = [numberFormatter stringFromNumber:stringFromNumber:#(1234.567800000555)];
This will actually print 1234.56780000056 (missing the 12th decimal place and rounding it up to the 11th decimal place) though I'm happy enough with this.
I'm still cleaning up the answer, I don't need maximumSignificantDigits = 100 obviously, but generally having a large number there helps to ensure I'm getting all the decimal places I need.
I had to set setGroupingSeparator:#"" because NSNumberFormatterDecimalStyle puts commas in numbers and I don't want them (eg: Instead of getting 1,000 I want 1000).

arc4random_uniform output issue

in iOS Objetive-C I am trying to get the number typed by the user in a text field to set the upper bounder of a random number generation function in C.
- (IBAction)pushTheButton2:(id)sender {
u_int32_t upperBound = (u_int32_t) textField3.text;
textField4.text = [NSString stringWithFormat:#"%d", arc4random_uniform(upperBound)];
}
The output is a giant number that makes no sense. To test if function works, if I hardcode the actual upper bound in the arc4random_uniform function, such as arc4random_uniform(5), then it works!
I figured this could be some kind of literal conversion, so I tried to make this work with u_int32_t but still not outputting the right range.
Can someone help? Thanks
You are currently taking the memory reference pointer of the text and using that as the upper bound.
Try doing something like this instead...
NSInteger upperBound = [textfield.text intValue];
This will convert the string into an int that you can then use in the arc random function.
To parse string to integer you should do:
NSInteger upperBound = [textfield.text integerValue];

Why is converting my float to an int making the number negative?

NSTimeInterval expirationTime = (secondsSinceUnixEpoch*1000)+120000;
expirationTime = ceil(expirationTime/2);
int expirationInt = (int)expirationTime;
NSLog(#"%d", expirationInt);
The log output is always negative, even though before I convert it to an int it's positive... I tried just multiplying it by -1 to make it positive again and it's just staying negative! I'm totally perplexed.... don't know much about C, am I just doing something silly??
The number (secondsSinceUnixEpoch*1000)+120000 looks to me like it's going to be way too large to fit in an int. Chances are the integer is overflowing and becoming negative.
Converting to long long is one solution. As you stated in a comment, you want to show a whole number for use in a URL. Just do this:
NSTimeInterval expirationTime = (secondsSinceUnixEpoch*1000)+120000;
expirationTime = ceil(expirationTime/2);
NSString *urlString = [NSString stringWithFormat:#"http://example.com?time=%.0f", expirationTime];
This will format the decimal number as a whole number.

Character code in NSString to unicode character

I have an NSString with a charactercode like this: 0x1F514.
I want to take this NSString and add it to another NSString, but not with the literal value of it, but the icon hidden behind it. In this case an emoticon of a bell.
How can I easily convert this NSString to show the emoticon instead of the character code?
Something like this would do:
NSString *c = #"0x1F514";
unsigned intVal;
NSScanner *scanner = [NSScanner scannerWithString:c];
[scanner scanHexInt:&intVal];
NSString *str = nil;
if (intVal > 0xFFFF) {
unsigned remainder = intVal - 0x10000;
unsigned topTenBits = (remainder >> 10) & 0x3FF;
unsigned botTenBits = (remainder >> 0) & 0x3FF;
unichar hi = topTenBits + 0xD800;
unichar lo = botTenBits + 0xDC00;
unichar unicodeChars[2] = {hi, lo};
str = [NSString stringWithCharacters:unicodeChars length:2];
} else {
unichar lo = (unichar)(intVal & 0xFFFF);
str = [NSString stringWithCharacters:&lo length:1];
}
NSLog(#"str = %#", str);
The reason simply #"\u1f514" doesn't work is because those \u values cannot be outside the BMP, i.e. >0xFFFF, i.e. >16-bit.
So, what my code does is check for that scenario and does the relevant surrogate pair magic to make the right string.
Hopefully that is actually what you want and makes sense!
If your NSString contains this "bell" character, then it does. You just append strings the usual way, like with stringByAppendingString.
The drawing of a bell instead of something denoting an unknown character is a completely separate issue. Your best bet is to ensure you're not using CoreText for drawing this, as it's been reported elsewhere, and I've seen it myself at work, that various non-standard characters may not work when printed that way. They do work, however, when printed with UIKit (that should be standard UI components, UIKitAdditions, and so on).
If using CoreText, you might get a bit lucky if you disable some text properties for the string with this special character, or choose appropriate font (but I won't help you here; we decided to leave the issue as Won't fix).
Having said that, the last time I was dealing with those was in pre-iOS 6 days...
Summary: your problem is not appending strings, but how you draw them.

Resources