Displaying leading zeroes in a timer xcode - xcode

I'm tying to display a countdown in my app. The timer works fine but I want it to display the time as 00:00:00. Leading zeroes on single digit integers are not ordinarily displayed (eg. 0:1:15) but I can't figure out how to get them in without resorting to clunky if-statements. Here is the relevant code:
-(void)timerFireMethod: (NSTimer *)timer {
[self setUpTimer];
self.timeLabel.text = [NSString stringWithFormat:#"%lu:%lu:%lu", self.timerParts.hour, self.timerParts.minute, self.timerParts.second];
self.counter--; }
Does anyone know what I can do to have the leading zeroes displayed so 0:1:15 becomes 00:01:15?

You can force to display leading zeros by adding .2.
It displays always two digits, in case of < 10 with a leading zero.
self.timeLabel.text = [NSString stringWithFormat:#"%.2lu:%.2lu:%.2lu", self.timerParts.hour, self.timerParts.minute, self.timerParts.second];

Related

NSDatePicker misbehaving with arrow keys

I have used NSDatePickers (without steppers) in the cells of a column in an NSTableView. The date pickers are used to set a duration of time in hours, minutes and seconds. If I highlight one of the controls and use the arrow keys to set the values, the date picker displays some weird behaviour:
Seconds increment by two for every time I press up arrow (whereas it should increment by one for each key press);
Seconds do not decrement when I press down arrow;
Every time I increment and decrement the minute and hour values, the seconds value also increases by one (each key press should only increment the selected value).
You can see this behaviour in the below example.
I have configured the NSDatePicker (result) as follows:
result = [[NSDatePicker alloc] initWithFrame:NSZeroRect];
result.identifier = #"timeCell";
result.tag = row;
[result setBordered:NO];
result.backgroundColor = [NSColor clearColor];
result.datePickerElements = NSHourMinuteSecondDatePickerElementFlag;
result.datePickerStyle = NSTextFieldDatePickerStyle;
result.timeZone = [NSTimeZone timeZoneForSecondsFromGMT:0];
[result setTarget:self];
[result setAction:#selector(timePickerDidChange:)];
Question: Does anyone know why this is happening and how I can fix it? Many thanks for your help.
PS: This question also touches on some weirdness surrounding arrow keys and NSDatePicker. It doesn't offer a solution though.

Objective-C EXC_BAD_ACCESS

Ok so I've recently decided to try to teach myself Objective-C (I'm interested in iPhone development), however I've never used C or any of its derivatives before, and as such am running into some problems.
I decided to start out by writing a very basic card application that creates a deck of cards, shuffles the deck, and then displays the cards on the screen using UIButtons, however I'm having a problem with my shuffling algorithm. Every time it gets called I get an EXC_BAD_ACCESS error, which I know means there's something desperately wrong with my code, but I just can't figure out what it is.
- (void) randomize {
NSMutableArray *tmpDeck = [[NSMutableArray alloc] init];
for(Card *tmp in _cards) {
BOOL didInsert = NO;
while(!didInsert) {
NSUInteger random = arc4random_uniform(54);
if([[tmpDeck objectAtIndex:random] isEqual:nil]) {
[tmpDeck insertObject:tmp atIndex:random];
didInsert = YES;
}
}
}
_cards = tmpDeck;
_hasBeenRandomized = YES;
}
_cards is a pointer to an NSMutableArray containing the unshuffled deck of card objects, and _hasBeenRandomized is a boolean (obviously) that keeps track of whether or not the deck has been randomized.
I've tried to use the debugger to work out what exactly is going on here, but I can't even step into the method without my program crashing. This leads me to believe that the problem has to come from the very first line, but it's just a straightforward creation of an NSMutableArray, so I don't know how it could be that. This method is being called from within viewDidLoad. This is the entirety of the viewDidLoad method currently.
- (void)viewDidLoad
{
[super viewDidLoad];
_deck = [[Deck alloc] init];
[_deck randomize];
}
Any and all help will be appreciated. Sorry if the answer is dead obvious.
This is because you are trying to insert into an index that doesn't exist yet. You need to initialize the array with as many places in the array as you need for your cards. Either that or use a NSMutableDictionary and just insert the object with the index being the key.
To add another note, calling initWithCapacity on the array wouldn't solve this for you either since this just gives a "hint" at the size. You need the count property of the array to actually be at least as large as the index you are trying to insert. If you wanted to do an array, then you would first need to populate something in each index first. You could define this in the new array literal format or use a for loop that loops the number of times you need (your max index) and insert a dummy object in it's place.
for (int i=0; i< _cards.count; ++i)
{
[tmpDeck insertObject:#"dummy" atIndex:i];
}
Then instead of checking for 'nil' before you replace, you check if it is equal to the dummy object you inserted. This would give you an array that you can insert into any of these indexes. I personally would still probably store them in an NSMutableDictionary. But if you need it in an array for some other purpose then this is a way to do it.
You also will need to be sure to replace the object instead of inserting, otherwise you will just keep adding indexes.
[tmpDeck replaceObjectAtIndex:random withObject:tmp];
If you still get the same error, set a breakpoint in your debugger and check what the random number is and what the count of your array is. If your random number is ever greater than your array count, then you will get this error.

Displaying currency signs in UILabel on Xcode

I am trying to display the gliphs for a currencies by using either the html format or unicode one. By using the former I tried all sorts of operations including: stringWithUTF8String, decodeFromPercentEscapeString, CFURLCreateStringByReplacingPercentEscapesUsingEncoding, stringByReplacingPercentEscapesUsingEncoding but none of them succeded in turning € into a euro sign. With Unicode the issue was slightly better as:
NSString *aStr = [NSString stringWithUTF8String:[#"\u20ac" UTF8String]];
actually prints a euro sign, but for I reason I do not understand, if I provide the string as the result of a method, the unicode code gets displayed instead.
What is the standard way for displaying euro, dollar or pounds signs in a UILbel?
UILabel automatically resolves unicode strings, no need to decode:
label.text = #"\u0024"; // dollar
label.text = #"\u20ac"; // euro
Refer to fileformat.info for the encoding name.
What about directly copying and pasting those characters in your string as :
NSString *aStr = #"Euro-€, Dollar-$, Pound-£";
label.text=aStr;
I found a very simple solution:
float fareValue=/*float value*/;
NSNumber* fareNumber=[NSNumber numberWithFloat:fareValue];
NSString* formatted=[NSNumberFormatter localizedStringFromNumber:fareNumber numberStyle:NSNumberFormatterCurrencyStyle];
Thanks everyone
Swift 3
"\u{00A3}"
The '#' is no longer needed

xcode How to show $ value in a Label and a Text Box. Example 125000 as 125,000.00

I need to show $value on a Label.
currently it appears as 125000 but i need it to be 125,000.00
thanks in advance to all supporters.
The solution of your problem is NSNumberFormatter
Some code to get you started:
NSNumberFormatter *currencyFormatter = [[NSNumberFormatter alloc] init];
[currencyFormatter setNumberStyle:NSNumberFormatterCurrencyStyle];
NSLog(#"%#", [currencyFormatter stringFromNumber:[NSNumber numberWithInt:10395209]]);
[currencyFormatter release];
Drag the Number Formatter (found in the object library) object onto the field/label. Change the behavior (be sure your in the attributes inspector for the number formatter) to 'OS X 10.4+ Custom' (that's what it was in Xcode 4.5.2).
In the 'Integer Digits' field, change the minimum to 1 and leave the maximum whatever you need. For the 'Fraction Digits' fields set the minimum and maximum to 2.
Near the top of the field, stick a dollar sign in front of the 'Format (+)' and '(-)' fields.
Check the group separator box then change the primary and secondary grouping fields to 3.

NSNumberFormatter doesn't allow typing decimal numbers

I am totally bewildered using NSNumberFormatter. This should be totally simple but I can't get it to work.
I'd like to set an NSTextField to allow typing decimal numbers, either with a decimal point or without. Here is what I'd think would work:
NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
[formatter setNumberStyle:NSNumberFormatterDecimalStyle];
[formatter setMinimumFractionDigits:0];
[formatter setMaximumFractionDigits:4];
[formatter setAllowsFloats:YES];
[[timeFlowMultiplierTF cell] setFormatter:formatter];
However, when typing in the textfield, pressing the "period" key for the decimal point doesn't yield one. Typing "3.14" give me "314". Throwing in [formatter setAlwaysShowsDecimalSeparator:YES] will initially format the number correctly, but if I type over it, I once again cannot type the decimal point.
What am I missing here? You would think this would be really simple
I realize this is about 4 years too late, but I just ran into this same nonsense and thought I'd share what the problem is (or could be), for posterity.
It turns out that all of the value accessors of NSTextField (-objectValue, -stringValue, -doubleValue, and so on) all end up calling -validateEditing. -validateEditing, in turn, uses the attached NSFormatter to convert the edited text into an object value, and then resets the text in the field with the reformatted value.
So if you have any code that watches the field as the user edits it and you "peek" at the value in the field, you are inadvertently reformatting and resetting the text in the text field.
It's not that the text field won't let you type a period; it's that is the text field already has "3" in it and when you type a period the text changes to "3.". If you then have an action/notification/delegate method that runs whenever something in the field changes, and you call any of the -typeValue methods, the "3." get formatted as "3" and it updates the cell, erasing the period you just typed.
My hack was to avoid the -typeValue methods and peek into the NSText object to get the edited text directly, without triggering -validateEditing:
// some method that runs every time the field changes...
NSTextField* valueField = self.valueField;
NSNumberFormatter* fieldFormatter = valueField.formatter;
NSText* fieldEditor = valueField.currentEditor;
id newValue = ( fieldEditor!=nil ? [fieldFormatter numberFromString:fieldEditor.string] : valueField.objectValue );
Thanks to and following on from #James Bucanek's answer: here is a Swift implementation that I've used when I was over-riding controlTextDidChange delegation method which unblocked the user from typing a decimal point. It also updates the enabled flag of a button on the interface according to if there's a valid (i.e > zero and non-zero length string) entry:
override func controlTextDidChange(notification: NSNotification) {
if let formatter: NSNumberFormatter? = self.user_textfield.formatter as? NSNumberFormatter {
if let field_editor: NSText = self.user_textfield.currentEditor() {
if let new_value: Float? = formatter!.numberFromString(field_editor.string!)?.floatValue {
self.my_button_out.enabled = new_value > 0.0
} else {
self.my_button_out.enabled = false
}
}
}
}

Resources