I have a UITextField in which the user enters an amount of money. I am trying to make the textField show the current money symbol, as the user types in an amount.
So far I was able to do that in textFieldDIdEndEditing:, how can I do the following code in a method that lets you change as the user types. (For example shouldChangeTextInRange:.) This way the currency will always show, not only when the user is finished entering the amount.
Here is what I have so far:
- (void)textFieldDidEndEditing:(UITextField *)textField {
NSNumberFormatter *currencyFormatter = [[[NSNumberFormatter alloc] init] autorelease];
[currencyFormatter setLocale:[NSLocale currentLocale]];
[currencyFormatter setMaximumFractionDigits:2];
[currencyFormatter setMinimumFractionDigits:2];
[currencyFormatter setAlwaysShowsDecimalSeparator:YES];
[currencyFormatter setNumberStyle:NSNumberFormatterCurrencyStyle];
NSNumber *someAmount = [NSNumber numberWithDouble:[textField.text doubleValue]];
NSString *string = [currencyFormatter stringFromNumber:someAmount];
textField.text = string;
}
The reason why I don't just insert it in a UILabel is because some places have their currency after the amount. (Ex. France)
Create a UIImageView with currency image.
And then set leftView either RightView of UITextField as per your requirement.
UIImage *cImage = [UIImage imageNamed:#"currency.png"];
UIImageView *imageView = [[UIImageView alloc] initWithImage:cImage];
[imageView setFrame:CGRectMake(0, 0, 40, 40)];
// For Left
[textfield setLeftView:imageView];
// or
// For Right
[textfield setRightView:imageView];
Try this.
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField
{
if (textField == txtAmount) {
if ([txtAmount.text isEqualToString:#""]) {
txtAmount.text = #"$";
}else{
txtAmount.text = [NSString stringWithFormat:#"%#",txtAmount.text];
}
}
return YES;
}
- (BOOL)textFieldShouldEndEditing:(UITextField *)textField
{
if (textField == txtAmount) {
if ([txtAmount.text isEqualToString:#"$"]) {
txtAmount.placeholder = #"Amount";
}
}
return YES;
}
and don't forget to give delegate to the UITextField.
Related
Currently, I created Array of UITextField based on Response from Server in my UI, My response contains three types of response in single API, i.e I get 5 key and Values. Values contains Types like String, Date, Array, based on this when I select the UITextFiled the value must change according to that Particular TextFiled
Here my Sample Code:
for (int i=0;i<itemAttributeArray.count;i++){
UIColor *floatingLabelColor = [UIColor brownColor];
textField1 = [[JVFloatLabeledTextField alloc] initWithFrame:CGRectMake(16, y, width, height)];
textField1.delegate = self;
//Set tag 101
textField1.tag = 101;
NSLog(#"textField1.tag - %ld",(long)textField1.tag);
textField1.text = [[itemAttributeArray valueForKey:#"value"]objectAtIndex:i];
[self SetTextFieldBorder:textField1];
textField1.placeholder = [keyArr objectAtIndex:i];
textField1.font = [UIFont systemFontOfSize:kJVFieldFontSize];
// textField1.clearsOnBeginEditing = YES;
textField1.clearButtonMode = UITextFieldViewModeWhileEditing;
textField1.floatingLabelFont = [UIFont boldSystemFontOfSize:kJVFieldFloatingLabelFontSize];
textField1.floatingLabelTextColor = floatingLabelColor;
// textField1.translatesAutoresizingMaskIntoConstraints = NO;
[textField1 resignFirstResponder];
[_scroll addSubview:textField1];
[textFields addObject:textField1];
[textField1 release];
y += height + margin;
if ([[[itemAttributeArray valueForKey:#"type"] objectAtIndex:i] isEqualToString:#"string"]){
NSLog(#"type - %#",[[itemAttributeArray valueForKey:#"type"] objectAtIndex:i]);
}else if ([[[itemAttributeArray valueForKey:#"type"]
objectAtIndex:i] isEqualToString:#"date"]){
NSLog(#"type - %#",[[itemAttributeArray valueForKey:#"type"] objectAtIndex:i]);
textField1.tag = 102;
[textField1 addTarget:self action:#selector(textFieldDidChange_dateChek)
forControlEvents:UIControlEventEditingDidBegin];
}else if ([[[itemAttributeArray valueForKey:#"type"] objectAtIndex:i] isEqualToString:#"double"]){
NSLog(#"type - %#",[[itemAttributeArray valueForKey:#"type"] objectAtIndex:i]);
}
-(void)textFieldDidChange_dateChek{
NSLog(#"iam called on first edit");
_picker_uiView.hidden = false;
[_datePickerView addTarget:self action:#selector(datePickerValueChanged:) forControlEvents:UIControlEventValueChanged];
}
- (void)datePickerValueChanged:(id)sender {
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"h:mm a"];
textField1.text = [dateFormatter
stringFromDate:_datePickerView.date];
}
When I select the date value is entered in the last object to UITextfield but I selected index is 2nd but values changing on the last element of UITextfield
you are create the textfield in globally, thats the reason you get the last index only. in here assign the tag for each textfield as well as create the instance value.for e.g
for (int i=0;i<itemAttributeArray.count;i++){
UIColor *floatingLabelColor = [UIColor brownColor];
JVFloatLabeledTextField *textField1 = [[JVFloatLabeledTextField alloc] initWithFrame:CGRectMake(16, y, width, height)];
textField1.delegate = self;
//Set tag 101
textField1.tag = 101 + i;
NSLog(#"textField1.tag - %ld",(long)textField1.tag);
textField1.text = [[itemAttributeArray valueForKey:#"value"]objectAtIndex:i];
[self SetTextFieldBorder:textField1];
textField1.placeholder = [keyArr objectAtIndex:i];
textField1.font = [UIFont systemFontOfSize:kJVFieldFontSize];
// textField1.clearsOnBeginEditing = YES;
textField1.clearButtonMode = UITextFieldViewModeWhileEditing;
textField1.floatingLabelFont = [UIFont boldSystemFontOfSize:kJVFieldFloatingLabelFontSize];
textField1.floatingLabelTextColor = floatingLabelColor;
// textField1.translatesAutoresizingMaskIntoConstraints = NO;
[textField1 resignFirstResponder];
[_scroll addSubview:textField1];
[textFields addObject:textField1];
[textField1 release];
y += height + margin;
if ([[[itemAttributeArray valueForKey:#"type"] objectAtIndex:i] isEqualToString:#"string"]){
NSLog(#"type - %#",[[itemAttributeArray valueForKey:#"type"] objectAtIndex:i]);
}else if ([[[itemAttributeArray valueForKey:#"type"] objectAtIndex:i] isEqualToString:#"date"]){
NSLog(#"type - %#",[[itemAttributeArray valueForKey:#"type"] objectAtIndex:i]);
[textField1 addTarget:self action:#selector(textFieldDidChange_dateChek:)
forControlEvents:UIControlEventEditingDidBegin];
}else if ([[[itemAttributeArray valueForKey:#"type"] objectAtIndex:i] isEqualToString:#"double"]){
}
}
and handle the textfield action
-(void)textFieldDidChange_dateChek:(JVFloatLabeledTextField*)textfield{
NSLog(#"iam called on first edit");
_picker_uiView.hidden = false;
_datePickerView.tag = textfield.tag;
[textfield resignFirstResponder];
[_datePickerView addTarget:self action:#selector(datePickerValueChanged:) forControlEvents:UIControlEventValueChanged];
textfield.inputView = _datePickerView;
}
finally assign the value to the textfield as like follow
- (void)datePickerValueChanged:(UIDatePicker*)sender {
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"h:mm a"];
// textField1.tag = 102;
for(id aSubView in [_scroll subviews]){
if([aSubView isKindOfClass:[JVFloatLabeledTextField class]])
{
JVFloatLabeledTextField *textFds=(JVFloatLabeledTextField*)aSubView;
if (textFds.tag == sender.tag) {
NSLog(#"dad == %#",[dateFormatter stringFromDate:sender.date]);
textFds.text = [dateFormatter stringFromDate:sender.date];
[textFds resignFirstResponder];
[sender removeFromSuperview];
break;
}
}
}
}
I am working on a chat application where i am using alex barinov's chat bubble example. I am able to send/receive messages. I want to add some labels and views on each chat bubble like time, date, delivered image, etc.
I tried to add some labels over the chat bubble's contentView in UIBubbleTableViewCell.m class in method named -(void)setupInternalData, but the label (date label) gets repeated for every bubble , and it overwrites the previous label, and it contains both the labels.
Here is the address from where i downloaded the project -https://github.com/AlexBarinov/UIBubbleTableView
Below is my code for adding labels to chat bubble view -
-(void)setupInternalData{
_fromLabel = [[UILabel alloc]initWithFrame:CGRectMake(self.frame.origin.x, self.frame.size.height-28, 100, 14)];
_fromLabel.numberOfLines = 1;
_fromLabel.baselineAdjustment = UIBaselineAdjustmentAlignBaselines;
_fromLabel.clipsToBounds = YES;
_fromLabel.layer.cornerRadius=5;
[_fromLabel setFont:[UIFont systemFontOfSize:5]];
[self.customView addSubview:_fromLabel];
//display msg sent time
NSDate *today = [NSDate date];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setTimeStyle:NSDateFormatterShortStyle];
[dateFormatter setDateStyle:NSDateFormatterMediumStyle];
NSString *currentTime = [dateFormatter stringFromDate:today];
_lblMsgTime.text=currentTime;
_lblMsgTime.frame=CGRectMake(12,0, 85, 14);
_lblMsgTime.text=[NSString stringWithFormat:#"%#",currentTime];
_lblMsgTime.textAlignment = NSTextAlignmentRight;
_lblMsgTime.textColor = [UIColor blackColor];
[_fromLabel addSubview:_lblMsgTime];
[_lblMsgTime setAdjustsFontSizeToFitWidth:YES];
//date formater
NSDate *date = [NSDate date];
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
formatter.dateFormat = #"d.M.yyyy";
[formatter setTimeStyle:NSDateFormatterShortStyle];
[formatter setDateStyle:NSDateFormatterMediumStyle];
NSString *string = [formatter stringFromDate:date];
_lblMsgdate.text=string;
_lblMsgdate.frame=CGRectMake(60 ,0, 85, 14);
_lblMsgdate.text=[NSString stringWithFormat:#"%#",string];
_lblMsgdate.textAlignment = NSTextAlignmentRight;
_lblMsgdate.textColor = [UIColor blackColor];
[_fromLabel addSubview:_lblMsgdate];
[_lblMsgdate setAdjustsFontSizeToFitWidth:YES];
UIImageView *backgroundView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"ic__typ__txt.png"]];
backgroundView.frame=CGRectMake(self.frame.origin.x+1, self.frame.size.height-24, 10, 10);
[self.customView addSubview:backgroundView];
[self.customView bringSubviewToFront:_fromLabel];
[self.customView bringSubviewToFront:backgroundView];
[self.contentView addSubview:self.customView];
}
Can anyone please tell me what wrong am i doing here, and what should i be doing. Any help is appreciated. Waiting for your valuable answers.
hey i think you have to create a view and pass it.
create a view in NSBubbleData file's
- (id)initWithText:(NSString *)text date:(NSDate *)date type:(NSBubbleType)type
{
UIFont *font = [UIFont systemFontOfSize:[UIFont systemFontSize]];
CGSize size = [(text ? text : #"") sizeWithFont:font constrainedToSize:CGSizeMake(220, 9999) lineBreakMode:NSLineBreakByWordWrapping];
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, size.width, size.height)];
label.numberOfLines = 0;
label.lineBreakMode = NSLineBreakByWordWrapping;
label.text = (text ? text : #"");
label.font = font;
label.backgroundColor = [UIColor clearColor];
#if !__has_feature(objc_arc)
[label autorelease];
#endif
UIEdgeInsets insets = (type == BubbleTypeMine ? textInsetsMine : textInsetsSomeone);
return [self initWithView:label date:date type:type insets:insets];
}
in this you have to create a view, in this view add uilable,uiimage which you want replace UILabel *label with custom view.
In My app I have a UITextField. When a user enters text such as 123456 it should appear something like 123,456.00 in the textfield.
The following code is used:
UITextField *txt = [[UITextField alloc]initWithFrame:CGRectMake(300, 120+y*58, 280, 31)];
txt.keyboardType = UIKeyboardTypeDecimalPad;
txt.borderStyle = UITextBorderStyleRoundedRect;
txt.font = [UIFont systemFontOfSize:15];
txt.textAlignment = NSTextAlignmentLeft;
txt.returnKeyType = UIReturnKeyDefault;
txt.delegate = self;
[txt addTarget:self action:#selector(textFieldDidChange:) forControlEvents:UIControlEventEditingChanged];
-(void)textFieldDidChange:(UITextField *)theTextField
{
NSString *textFieldText = [theTextField.text stringByReplacingOccurrencesOfString:#"," withString:#""];
NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
[formatter setNumberStyle:NSNumberFormatterDecimalStyle];
NSNumber *number = [formatter numberFromString:textFieldText];
NSString *formattedOutput = [formatter stringFromNumber:number];
theTextField.text=formattedOutput;
}
Use below code
NSString *textFieldText = theTextField.text ;
float f = [theString floatValue];
NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
[formatter setNumberStyle:NSNumberFormatterDecimalStyle];
[formatter setMinimumFractionDigits:2];
[formatter setMaximumFractionDigits:2];
[formatter setLocale:[NSLocale currentLocale]];
NSLog(#"%#", [formatter stringFromNumber:#(f)]);
Set MinimumFractionDigits to 2 & MaximumFractionDigits to 2.Try above code in textFieldDidEndEditing delegate method of textfield.
You are almost close to your solution just few things need enhancement. First you must have to specify the maximum and minimum allowed fractions digits like this:
[formatter setMinimumFractionDigits:2];
[formatter setMaximumFractionDigits:2];
It will fix the *.00 problem, then there is another problem of updating it back to the UI. Since you are setting the textfield text:
theTextField.text=formattedOutput;
It will lose the current position of editing and hence you will lose the ground. e.g.,
You typed 1, the above code will update the textfield with 1.00 and the cursor will move to position 5:
1.00
^^^^^
If you will edit further you won't get the expected result (the text will try to append at the end).
To fix this either you should update the text field when you finish editing using the handler textFieldDidEndEditing or you should use some other control like UILabel to display the formatted result.
Sample Code: (for demo)
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
UITextField *txt = [[UITextField alloc]initWithFrame:CGRectMake(20, 120+(3)*58, 280, 31)];
txt.keyboardType = UIKeyboardTypeDecimalPad;
txt.borderStyle = UITextBorderStyleRoundedRect;
txt.font = [UIFont systemFontOfSize:15];
txt.textAlignment = NSTextAlignmentLeft;
txt.returnKeyType = UIReturnKeyDefault;
txt.delegate = self;
[self.view addSubview:txt];
[txt addTarget:self action:#selector(textFieldDidChange:) forControlEvents:UIControlEventEditingChanged];
lbl = [[UILabel alloc] initWithFrame:CGRectMake(20, 160+(3)*58, 280, 31)];
[self.view addSubview:lbl];
}
-(void)textFieldDidChange:(UITextField *)theTextField
{
NSString *textFieldText = [theTextField.text stringByReplacingOccurrencesOfString:#"," withString:#""];
NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
[formatter setNumberStyle:NSNumberFormatterDecimalStyle];
[formatter setMinimumFractionDigits:2];
[formatter setMaximumFractionDigits:2];
NSNumber *number = [formatter numberFromString:textFieldText];
NSString *formattedOutput = [formatter stringFromNumber:number];
[lbl setText:formattedOutput];
}
You can set text like this to your textview.
theTextField.text = [NSString stringWithFormat:#"%.02f", floatVal];
Hope this helps.
If you add these two lines to the code snippet you posted:
[formatter setMinimumFractionDigits:2];
[formatter setMaximumFractionDigits:2];
right after the line in which you set the number formatter's style to NSNumberFormatterDecimalStyle, it should give you exactly what you want.
#"123456" would result in #"123,456.00"
and #"1" would result in #"1.00"
I'm currently showing a Date Picker of the kind UIDatePickerModeCountDownTimer that uses:
- (UIDatePicker *)datePicker {
if (!_datePicker) {
_datePicker = [[UIDatePicker alloc] init];
_datePicker.datePickerMode = UIDatePickerModeCountDownTimer;
_datePicker.backgroundColor = [UIColor colorWithWhite:1.0 alpha:0.8];
}
return _datePicker;
}
- (void)setDuration:(NSTimeInterval)duration {
_duration = duration;
self.datePicker.countDownDuration = _duration;
}
... date picker, and shows (in a label) the time from current date to date chosen in future with:
- (void)update {
if (self.time) {
[self setImage:nil forState:UIControlStateNormal];
NSString *title;
NSTimeInterval timeInterval = [self.time doubleValue];
if (self.ticking) {
NSMutableString *dateFormat = [[NSMutableString alloc] init];
if (timeInterval < 0) {
[dateFormat appendString:#"-"];
}
if (fabsf(timeInterval) > 60 * 60) {
[dateFormat appendString:#"hh:"];
}
[dateFormat appendString:#"mm:ss"];
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
formatter.dateFormat = dateFormat;
formatter.timeZone = [NSTimeZone timeZoneForSecondsFromGMT:0];
NSDate *date = [NSDate dateWithTimeIntervalSince1970:timeInterval];
title = [formatter stringFromDate:date];
if ([self.time integerValue] > 0) {
self.circleView.backgroundColor = [UIColor colorWithRed:0.373 green:0.702 blue:0.522 alpha:1];
} else {
self.circleView.backgroundColor = [UIColor colorWithRed:0.820 green:0.373 blue:0.424 alpha:1];
}
} else {
NSMutableString *text = [[NSMutableString alloc] init];
if (fabsf(timeInterval) < 60) {
// Show seconds
[text appendFormat:#"%.0fs", timeInterval];
} else if (fabsf(timeInterval) < 60 * 60) {
// Show minutes
[text appendFormat:#"%.0fm", floorf(timeInterval / 60)];
} else {
// Show hours
[text appendFormat:#"%.0fh", floorf(timeInterval / 60 / 60)];
}
title = text;
self.circleView.backgroundColor = [UIColor colorWithWhite:1.0f alpha:0.2];
}
[self setTitle:title forState:UIControlStateNormal];
return;
}
[self setTitle:nil forState:UIControlStateNormal];
[self setImage:[UIImage imageNamed:#"plus"] forState:UIControlStateNormal];
self.circleView.backgroundColor = [UIColor colorWithWhite:1.0f alpha:0.05];
}
... but I switched the DatePicker to UIDatePickerModeDateAndTime and need to figure out how to update my update method with it.
I need to show month/day in addition to hour/minute/second in the label.
If you want a method like delegate, then this can help you..
Add target to your date picker....
[myDatePicker addTarget:self action:#selector(onPickerValueChanged:) forControlEvents:UIControlEventValueChanged];
Remove target in dealloc. Otherwise if your picker is scrolling and viewController is popped, app will crash.
- (void dealloc
{
[myPicker removeTarget:self action:#selector(onPickerValueChanged:) forControlEvents:UIControlEventValueChanged];
[myPicker release];//FOR NON ARC
[super dealloc];//FOR NON ARC
}
Implement value Change like
- (IBAction)onPickerValueChanged:(id)sender
{
[self update];
}
I am trying to dectect if an NSString it's a float number, for exemple : #"-73.041382"
But when I try with this method I obtain a wrong result:
-(bool) isNumeric:(NSString*) checkText{
NSNumberFormatter* numberFormatter = [[[NSNumberFormatter alloc] init] autorelease];
NSNumber* number = [numberFormatter numberFromString:checkText];
if (number != nil) {
return true;
}
return false;
}
Someone have an idea!?
Thanks
I have found the answer :
-(bool) isNumeric:(NSString*) checkText{
NSNumberFormatter* numberFormatter = [[[NSNumberFormatter alloc] init] autorelease];
//Set the locale to US
[numberFormatter setLocale:[[[NSLocale alloc] initWithLocaleIdentifier:#"en_US"] autorelease]];
//Set the number style to Scientific
[numberFormatter setNumberStyle:NSNumberFormatterScientificStyle];
NSNumber* number = [numberFormatter numberFromString:checkText];
if (number != nil) {
return true;
}
return false;
}
Thanks!
-(bool) isNumeric:(NSString*) checkText{
return [[NSScanner scannerWithString:checkText] scanFloat:NULL];
}
i'm currently not on mac so i can't check it, hope it helps