Skip to content
This repository was archived by the owner on Apr 6, 2024. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 2 additions & 5 deletions FormattedCurrencyInput/ViewController.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,6 @@

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController <UITextFieldDelegate>
@interface ViewController : UIViewController

@property (strong, nonatomic) IBOutlet UITextField *textField;
- (IBAction)valueButton:(id)sender;

@end
@end
164 changes: 102 additions & 62 deletions FormattedCurrencyInput/ViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -8,60 +8,110 @@

#import "ViewController.h"

@interface ViewController ()
static NSUInteger const kMaxLength = 11;

typedef NS_ENUM(NSUInteger, InputType) {
InputTypeRegular,
InputTypeSuffix
};

@interface ViewController ()<UITextFieldDelegate>

@property (nonatomic, weak) IBOutlet UITextField *textField;
@property (nonatomic, weak) IBOutlet UITextField *suffixField;

@property (nonatomic, strong) NSNumberFormatter *regularFormatter;
@property (nonatomic, strong) NSNumberFormatter *suffixFormatter;

- (IBAction)valueButton:(id)sender;

@end

@implementation ViewController

@synthesize textField = _textField;

#pragma mark - View Life Cycle
- (void)viewDidLoad
{
[super viewDidLoad];
_textField.delegate = self;

NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init];
[numberFormatter setNumberStyle:NSNumberFormatterCurrencyStyle];
[numberFormatter setMaximumFractionDigits:2];
[numberFormatter setMinimumFractionDigits:2];

_textField.text = [numberFormatter stringFromNumber:[NSNumber numberWithInt:0]];
self.textField.text = [self.regularFormatter stringFromNumber:@0];
self.suffixField.text = [self.suffixFormatter stringFromNumber:@0];
}

- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[self.textField becomeFirstResponder];
}

- (void)didReceiveMemoryWarning
#pragma mark - Accessors
- (NSNumberFormatter *) regularFormatter
{
[super didReceiveMemoryWarning];
if (_regularFormatter)
{
return _regularFormatter;
}

_regularFormatter = [[NSNumberFormatter alloc] init];
_regularFormatter.numberStyle = NSNumberFormatterCurrencyStyle;
_regularFormatter.maximumFractionDigits = 2;
_regularFormatter.minimumFractionDigits = 2;

return _regularFormatter;
}

- (IBAction)valueButton:(id)sender
- (NSNumberFormatter *) suffixFormatter
{
NSString *textFieldStr = [NSString stringWithFormat:@"%@", _textField.text];
if (_suffixFormatter)
{
return _suffixFormatter;
}

NSMutableString *textFieldStrValue = [NSMutableString stringWithString:textFieldStr];
_suffixFormatter = [[NSNumberFormatter alloc] init];
_suffixFormatter.numberStyle = NSNumberFormatterCurrencyStyle;
_suffixFormatter.positiveFormat = @"#,##0.00¤";
_suffixFormatter.negativeFormat = @"(#,##0.00¤";
_suffixFormatter.currencySymbol = @"YTL";

NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init];
[numberFormatter setNumberStyle:NSNumberFormatterCurrencyStyle];
return _suffixFormatter;
}

[textFieldStrValue replaceOccurrencesOfString:numberFormatter.currencySymbol
withString:@""
options:NSLiteralSearch
range:NSMakeRange(0, [textFieldStrValue length])];

[textFieldStrValue replaceOccurrencesOfString:numberFormatter.groupingSeparator
withString:@""
options:NSLiteralSearch
range:NSMakeRange(0, [textFieldStrValue length])];
#pragma mark - private
- (NSString *) valueFromString:(NSString *)string
{
NSCharacterSet *valueSet= [[NSCharacterSet characterSetWithCharactersInString:@"0123456789,."] invertedSet];
return [[[string componentsSeparatedByCharactersInSet:valueSet] componentsJoinedByString:@""] mutableCopy];
}

- (NSString *) numberFromString:(NSString *)string
{
NSCharacterSet *numberSet = [[NSCharacterSet characterSetWithCharactersInString:@"0123456789"] invertedSet];
return [[[string componentsSeparatedByCharactersInSet:numberSet] componentsJoinedByString:@""] mutableCopy];
}

- (NSDecimalNumber *) dividerForFormatter:(NSNumberFormatter *)formatter
{
return [[[NSDecimalNumber alloc] initWithInt:10] decimalNumberByRaisingToPower:formatter.maximumFractionDigits];
}

- (NSString *) alertTextForField:(UITextField *)field formatter:(NSNumberFormatter *)formatter
{
NSDecimalNumber *textFieldNum = [NSDecimalNumber decimalNumberWithString:[self numberFromString:field.text]];
textFieldNum = [textFieldNum decimalNumberByDividingBy:[self dividerForFormatter:formatter]];
return [NSString stringWithFormat:@"Value:%@\nNumber:%@", field.text, textFieldNum];
}

NSDecimalNumber *textFieldNum = [NSDecimalNumber decimalNumberWithString:textFieldStrValue];
#pragma mark - Action
- (IBAction)valueButton:(id)sender
{
NSString *regular = [self alertTextForField:self.textField formatter:self.regularFormatter];
NSString *suffix = [self alertTextForField:self.suffixField formatter:self.suffixFormatter];
NSString *message = [NSString stringWithFormat:@"Regular\n%@\n\nSuffix\n%@", regular, suffix];

UIAlertView* alert = [[UIAlertView alloc] initWithTitle:nil
message:[NSString stringWithFormat:@"Value: %@, Number: %@", textFieldStr, textFieldNum]
message:message
delegate:nil
cancelButtonTitle:@"Ok"
otherButtonTitles:nil];
Expand All @@ -70,30 +120,24 @@ - (IBAction)valueButton:(id)sender

- (BOOL)textField:(UITextField*)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString*)string
{
NSInteger MAX_DIGITS = 11; // $999,999,999.99
NSNumberFormatter *formatter;

NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init];
[numberFormatter setNumberStyle:NSNumberFormatterCurrencyStyle];
[numberFormatter setMaximumFractionDigits:2];
[numberFormatter setMinimumFractionDigits:2];
if (textField.tag == InputTypeSuffix)
{
formatter = self.suffixFormatter;
}
else
{
formatter = self.regularFormatter;
}

NSString *stringMaybeChanged = [NSString stringWithString:string];
if (stringMaybeChanged.length > 1)
{
NSMutableString *stringPasted = [NSMutableString stringWithString:stringMaybeChanged];

[stringPasted replaceOccurrencesOfString:numberFormatter.currencySymbol
withString:@""
options:NSLiteralSearch
range:NSMakeRange(0, [stringPasted length])];

[stringPasted replaceOccurrencesOfString:numberFormatter.groupingSeparator
withString:@""
options:NSLiteralSearch
range:NSMakeRange(0, [stringPasted length])];

stringPasted = [[self numberFromString:stringPasted] mutableCopy];
NSDecimalNumber *numberPasted = [NSDecimalNumber decimalNumberWithString:stringPasted];
stringMaybeChanged = [numberFormatter stringFromNumber:numberPasted];
stringMaybeChanged = [formatter stringFromNumber:numberPasted];
}

UITextRange *selectedRange = [textField selectedTextRange];
Expand All @@ -102,29 +146,25 @@ - (BOOL)textField:(UITextField*)textField shouldChangeCharactersInRange:(NSRange
NSMutableString *textFieldTextStr = [NSMutableString stringWithString:textField.text];
NSUInteger textFieldTextStrLength = textFieldTextStr.length;

[textFieldTextStr replaceCharactersInRange:range withString:stringMaybeChanged];

[textFieldTextStr replaceOccurrencesOfString:numberFormatter.currencySymbol
withString:@""
options:NSLiteralSearch
range:NSMakeRange(0, [textFieldTextStr length])];
NSUInteger originalLength = textFieldTextStr.length;
textFieldTextStr = [[self valueFromString:textFieldTextStr] mutableCopy];
NSUInteger newLength = textFieldTextStr.length;
range.location += newLength - originalLength;

[textFieldTextStr replaceOccurrencesOfString:numberFormatter.groupingSeparator
withString:@""
options:NSLiteralSearch
range:NSMakeRange(0, [textFieldTextStr length])];

[textFieldTextStr replaceOccurrencesOfString:numberFormatter.decimalSeparator
withString:@""
options:NSLiteralSearch
range:NSMakeRange(0, [textFieldTextStr length])];
[textFieldTextStr replaceCharactersInRange:range withString:stringMaybeChanged];
textFieldTextStr = [[self numberFromString:textFieldTextStr] mutableCopy];

if (textFieldTextStr.length <= MAX_DIGITS)
if (textFieldTextStr.length <= kMaxLength)
{
NSDecimalNumber *textFieldTextNum = [NSDecimalNumber decimalNumberWithString:textFieldTextStr];
NSDecimalNumber *divideByNum = [[[NSDecimalNumber alloc] initWithInt:10] decimalNumberByRaisingToPower:numberFormatter.maximumFractionDigits];
NSDecimalNumber *textFieldTextNewNum = [textFieldTextNum decimalNumberByDividingBy:divideByNum];
NSString *textFieldTextNewStr = [numberFormatter stringFromNumber:textFieldTextNewNum];
NSDecimalNumber *divideByNum = [self dividerForFormatter:formatter];
NSString *textFieldTextNewStr;

if (!isnan(textFieldTextNum.doubleValue))
{
NSDecimalNumber *textFieldTextNewNum = [textFieldTextNum decimalNumberByDividingBy:divideByNum];
textFieldTextNewStr = [formatter stringFromNumber:textFieldTextNewNum];
}

textField.text = textFieldTextNewStr;

Expand Down
65 changes: 34 additions & 31 deletions FormattedCurrencyInput/en.lproj/MainStoryboard.storyboard
Original file line number Diff line number Diff line change
@@ -1,52 +1,72 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="2.0" toolsVersion="3084" systemVersion="12E55" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" initialViewController="2">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="9059" systemVersion="15B42" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" initialViewController="2">
<dependencies>
<deployment defaultVersion="1552" identifier="iOS"/>
<development version="4600" identifier="xcode"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="2083"/>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="9049"/>
</dependencies>
<scenes>
<!--View Controller-->
<scene sceneID="5">
<objects>
<viewController id="2" customClass="ViewController" sceneMemberID="viewController">
<layoutGuides>
<viewControllerLayoutGuide type="top" id="CvZ-DG-bNk"/>
<viewControllerLayoutGuide type="bottom" id="fII-PJ-2Hf"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="3">
<rect key="frame" x="0.0" y="20" width="320" height="548"/>
<rect key="frame" x="0.0" y="0.0" width="320" height="568"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="eIF-en-8Z3">
<rect key="frame" x="60" y="20" width="200" height="30"/>
<animations/>
<constraints>
<constraint firstAttribute="width" constant="200" id="fXq-cL-NRx"/>
</constraints>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<textInputTraits key="textInputTraits" keyboardType="numberPad"/>
<connections>
<outlet property="delegate" destination="2" id="tr7-fP-ZcQ"/>
</connections>
</textField>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="lxs-RT-6ar">
<rect key="frame" x="123" y="114" width="73" height="30"/>
<animations/>
<constraints>
<constraint firstAttribute="width" constant="73" id="pTK-FJ-i1W"/>
</constraints>
<fontDescription key="fontDescription" type="boldSystem" pointSize="15"/>
<state key="normal" title="Value?">
<color key="titleColor" red="0.19607843459999999" green="0.30980393290000002" blue="0.52156865600000002" alpha="1" colorSpace="calibratedRGB"/>
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
</state>
<state key="highlighted">
<color key="titleColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
</state>
<connections>
<action selector="valueButton:" destination="2" eventType="touchUpInside" id="csk-e8-MjS"/>
</connections>
</button>
<textField opaque="NO" clipsSubviews="YES" tag="1" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" textAlignment="natural" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="6Sn-Jx-Bgj">
<rect key="frame" x="60" y="67" width="200" height="30"/>
<animations/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<textInputTraits key="textInputTraits"/>
<connections>
<outlet property="delegate" destination="2" id="pRt-wF-Byj"/>
</connections>
</textField>
</subviews>
<animations/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
<constraints>
<constraint firstItem="lxs-RT-6ar" firstAttribute="top" secondItem="eIF-en-8Z3" secondAttribute="bottom" constant="8" symbolic="YES" type="default" id="7n4-DU-H2T"/>
<constraint firstItem="lxs-RT-6ar" firstAttribute="centerX" secondItem="eIF-en-8Z3" secondAttribute="centerX" type="default" id="B5u-55-Z6j"/>
<constraint firstItem="eIF-en-8Z3" firstAttribute="centerX" secondItem="3" secondAttribute="centerX" type="default" id="eoh-K6-PYD"/>
<constraint firstItem="eIF-en-8Z3" firstAttribute="top" secondItem="3" secondAttribute="top" constant="20" symbolic="YES" type="default" id="yeZ-rS-ve0"/>
<constraint firstItem="lxs-RT-6ar" firstAttribute="centerX" secondItem="eIF-en-8Z3" secondAttribute="centerX" id="B5u-55-Z6j"/>
<constraint firstItem="lxs-RT-6ar" firstAttribute="top" secondItem="6Sn-Jx-Bgj" secondAttribute="bottom" constant="17" id="Sum-3G-H8L"/>
<constraint firstItem="6Sn-Jx-Bgj" firstAttribute="top" secondItem="eIF-en-8Z3" secondAttribute="bottom" constant="17" id="WCJ-jy-A9E"/>
<constraint firstItem="6Sn-Jx-Bgj" firstAttribute="centerX" secondItem="eIF-en-8Z3" secondAttribute="centerX" id="bp4-gV-STN"/>
<constraint firstItem="eIF-en-8Z3" firstAttribute="centerX" secondItem="3" secondAttribute="centerX" id="eoh-K6-PYD"/>
<constraint firstItem="6Sn-Jx-Bgj" firstAttribute="width" secondItem="eIF-en-8Z3" secondAttribute="width" id="nWw-zV-wkZ"/>
<constraint firstItem="eIF-en-8Z3" firstAttribute="top" secondItem="3" secondAttribute="top" constant="20" symbolic="YES" id="yeZ-rS-ve0"/>
</constraints>
</view>
<connections>
<outlet property="suffixField" destination="6Sn-Jx-Bgj" id="u69-yP-Yv2"/>
<outlet property="textField" destination="eIF-en-8Z3" id="dKj-zU-SfN"/>
</connections>
</viewController>
Expand All @@ -55,21 +75,4 @@
<point key="canvasLocation" x="88" y="11"/>
</scene>
</scenes>
<classes>
<class className="NSLayoutConstraint" superclassName="NSObject">
<source key="sourceIdentifier" type="project" relativePath="./Classes/NSLayoutConstraint.h"/>
</class>
<class className="ViewController" superclassName="UIViewController">
<source key="sourceIdentifier" type="project" relativePath="./Classes/ViewController.h"/>
<relationships>
<relationship kind="action" name="valueButton:"/>
<relationship kind="outlet" name="textField" candidateClass="UITextField"/>
</relationships>
</class>
</classes>
<simulatedMetricsContainer key="defaultSimulatedMetrics">
<simulatedStatusBarMetrics key="statusBar"/>
<simulatedOrientationMetrics key="orientation"/>
<simulatedScreenMetrics key="destination" type="retina4"/>
</simulatedMetricsContainer>
</document>
</document>