Format Numbers in Textfields using Swift - xcode

I am trying to format a number from a UITextfield, as its being typed, to a decimal with commas.
I have done so with the following code:
#IBAction func editingDidBegin(sender : AnyObject)
{
costField.addTarget(self, action: Selector("textFieldDidChange:"), forControlEvents: UIControlEvents.EditingChanged)
}
func textFieldDidChange(theTextField:UITextField) -> Void
{
var textFieldText = theTextField.text.stringByReplacingOccurrencesOfString(",", withString: " ", options: NSStringCompareOptions.RegularExpressionSearch, range: Range(start: theTextField.text.startIndex, end: theTextField.text.endIndex))
var formatter:NSNumberFormatter = NSNumberFormatter()
formatter.numberStyle = NSNumberFormatterStyle.DecimalStyle
var formattedOutput = formatter.stringFromNumber(textFieldText.bridgeToObjectiveC().integerValue)
costField.text = formattedOutput
}
The problem with this, is after four digits are entered, everything after the comma is deleted. For example if I enter 4000 it formats to 4,000, then if I type another number like 8 it reformats to 48.
Is there another way I can format this, maybe through IB or how can I fix the code?

Replace the line with:
var textFieldText = theTextField.text.stringByReplacingOccurrencesOfString(",", withString: "", options: NSStringCompareOptions.RegularExpressionSearch, range: Range(start: theTextField.text.startIndex, end: theTextField.text.endIndex))
(I only removed the space between the double quotes).
Fact is, NSNumberFormatter doesn't like the added spaces in the string.
Works fine afterwards.

I know I am late to the party but this worked well for me.
var phoneNumber = " 1 (888) 555-5551 "
var strippedPhoneNumber = "".join(phoneNumber.componentsSeparatedByCharactersInSet(NSCharacterSet.decimalDigitCharacterSet().invertedSet))
It takes out the spaces and strips out the non decimal numeric characters.
The end result is "1888555551"

I've updated this answer to the newest version of swift. This borrows 90% from the two answers above however, also accounts for nil exception from the textfield when the textfield is cleared.
func textFieldDidChangeCommas(theTextField:UITextField) -> Void
{
if theTextField.text != nil {
var textFieldText = theTextField.text!.stringByReplacingOccurrencesOfString(",", withString: "", options: NSStringCompareOptions.RegularExpressionSearch, range: Range(start: theTextField.text!.startIndex, end: theTextField.text!.endIndex))
var formatter:NSNumberFormatter = NSNumberFormatter()
formatter.numberStyle = NSNumberFormatterStyle.DecimalStyle
if textFieldText != "" {
var formattedOutput = formatter.stringFromNumber(Int(textFieldText)!)
costField.text = formattedOutput
}
}
}

Related

Regular expression

I want the user to enter text in a text field, and if the user types "<" a space should be automatically appended to the text in the field
I tried removing the special character but I need the user to input that as well.
let RISTRICTED_CHARACTERS = "<"
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
let set = CharacterSet(charactersIn: RISTRICTED_CHARACTERS)
let inverted = set.inverted
let filtered = string.components(separatedBy: inverted).joined(separator: "")
if filtered == string && string != "" {
return false
} else {
let maxLength = maxLenghtOfTextField
let currentString: NSString = textField.text! as NSString
let newString: NSString = currentString.replacingCharacters(in: range, with: string) as NSString
return newString.length <= maxLength
}
In this code I'm not allowing "<" this character. I want the text field to be like this.
My output should be : hello <(space) world.
The space should be automatically appended if I start with "<" sign.
Instead of .replacingCharacters maybe try .replacingOccurences
let updatedString: String? = textField.text.replacingOccurrences(of: "<", with: " ")

How can I find the substrings from the NSTextCheckingResult objects in swift?

I wonder how it is possible to find substrings from a NSTextCheckingResult object. I have tried this so far:
import Foundation {
let input = "My name Swift is Taylor Swift "
let regex = try NSRegularExpression(pattern: "Swift|Taylor", options:NSRegularExpressionOptions.CaseInsensitive)
let matches = regex.matchesInString(input, options: [], range: NSMakeRange(0, input.characters.count))
for match in matches {
// what will be the code here?
}
Try this:
import Foundation
let input = "My name Swift is Taylor Swift "// the input string where we will find for the pattern
let nsString = input as NSString
let regex = try NSRegularExpression(pattern: "Swift|Taylor", options: NSRegularExpressionOptions.CaseInsensitive)
//matches will store the all range objects in form of NSTextCheckingResult
let matches = regex.matchesInString(input, options: [], range: NSMakeRange(0, input.characters.count)) as Array<NSTextCheckingResult>
for match in matches {
// what will be the code
let range = match.range
let matchString = nsString.substringWithRange(match.range) as String
print("match is \(range) \(matchString)")
}
Here is code that works for Swift 3. It returns array of String
results.map {
String(text[Range($0.range, in: text)!])
}
So overall example could be like this:
let regex = try NSRegularExpression(pattern: regex)
let results = regex.matches(in: text,
range: NSRange(text.startIndex..., in: text))
return results.map {
String(text[Range($0.range, in: text)!])
}
You can put this code inside the for loop. The str will contain the string that matches.
let range = match.range
let str = (input as NSString).substringWithRange(range)

Xcode Air print

I am a beginner with xcode and swift.
I have a couple of fields and a image in my viewcontroller and I would like to print the content of this fields...
My code from a tutorial:
#IBAction func print(sender: AnyObject) {
// 1
let printController = UIPrintInteractionController.sharedPrintController()
// 2
let printInfo = UIPrintInfo(dictionary:nil)
printInfo.outputType = UIPrintInfoOutputType.General
printInfo.jobName = "Rapport"
printController.printInfo = printInfo
// 3
let formatter = UIMarkupTextPrintFormatter(markupText: itemName.text!)
formatter.contentInsets = UIEdgeInsets(top: 72, left: 72, bottom: 72, right: 72)
printController.printFormatter = formatter
// 4
printController.presentAnimated(true, completionHandler: nil)
}
works very well with this only textfield. But how can I print the rest of it?
You are using a formatter to send to the printController and send him a markup text to print. This function takes a string, so you can create a custom string with all the text you want it to have and call the function, like this:
// 3
let myMarkupText = itemName.text! + "\n" + secondField.text! + "\n" + anotherField.text!
let formatter = UIMarkupTextPrintFormatter(markupText: myMarkupText)
...
I added the "\n" to start a new line, but you can format it the way you want, of course. I'm not sure if "\n" would create a new line anyway (since this is markup, maybe you need <br />), you'd have to try and see.
If you wanted to print the whole page instead of just certain parts, you could also check the documentation for UIPrintInteractionController to see what other options you have (printingItem, printingItems, printPageRenderer).
Alternatively, if you have a long string with multiple \n carriage returns, you need to first replace all of the \n occurrences with br / before submitting the string to the UIMarkupTextPrintFormatter. Here is an example for Swift 4:
func print(text: String) {
let textWithNewCarriageReturns = text.replacingOccurrences(of: "\n", with: "<br />")
let printController = UIPrintInteractionController.shared
let printInfo = UIPrintInfo(dictionary: nil)
printInfo.outputType = UIPrintInfoOutputType.general
printController.printInfo = printInfo
let format = UIMarkupTextPrintFormatter(markupText: textWithNewCarriageReturns)
format.perPageContentInsets.top = 72
format.perPageContentInsets.bottom = 72
format.perPageContentInsets.left = 72
format.perPageContentInsets.right = 72
printController.printFormatter = format
printController.present(animated: true, completionHandler: nil)
}

xcode: need to convert strings to double and back to string

this is my line of code.
budgetLabel.text = String((budgetLabel.text)!.toInt()! - (budgetItemTextBox.text)!.toInt()!)
the code works, but when I try to input a floating value into the textbox the program crashes. I am assuming the strings need to be converted to a float/double data type. I keep getting errors when i try to do that.
In Swift 2 there are new failable initializers that allow you to do this in more safe way, the Double("") returns an optional in cases like passing in "abc" string the failable initializer will return nil, so then you can use optional-binding to handle it like in the following way:
let s1 = "4.55"
let s2 = "3.15"
if let n1 = Double(s1), let n2 = Double(s2) {
let newString = String( n1 - n2)
print(newString)
}
else {
print("Some string is not a double value")
}
If you're using a version of Swift < 2, then old way was:
var n1 = ("9.99" as NSString).doubleValue // invalid returns 0, not an optional. (not recommended)
// invalid returns an optional value (recommended)
var pi = NSNumberFormatter().numberFromString("3.14")?.doubleValue
Fixed: Added Proper Handling for Optionals
let budgetLabel:UILabel = UILabel()
let budgetItemTextBox:UITextField = UITextField()
budgetLabel.text = ({
var value = ""
if let budgetString = budgetLabel.text, let budgetItemString = budgetItemTextBox.text
{
if let budgetValue = Float(budgetString), let budgetItemValue = Float(budgetItemString)
{
value = String(budgetValue - budgetItemValue)
}
}
return value
})()
You need to be using if let. In swift 2.0 it would look something like this:
if let
budgetString:String = budgetLabel.text,
budgetItemString:String = budgetItemTextBox.text,
budget:Double = Double(budgetString),
budgetItem:Double = Double(budgetItemString) {
budgetLabel.text = String(budget - budgetItem)
} else {
// If a number was not found, what should it do here?
}

NSTextlist issue in Swift

I wrote the following code to get list in a nstextview. The issue is, in first line number (1) is appearing correctly and after entering some data and press enter second line number (2) should automatically appear. but it isn't. Any help is appreciated
#IBAction func numberList(sender: AnyObject) {
self.editorView.textStorage?.beginEditing()
var paragraph : NSMutableParagraphStyle = NSMutableParagraphStyle()
var textList : NSTextList = NSTextList(markerFormat: "{decimal}.", options: 0)
paragraph.textLists = [textList]
var attributedString : NSAttributedString = NSAttributedString(string: "\t \(textList.markerForItemNumber(1)) \t", attributes: [paragraph : NSParagraphStyleAttributeName])
self.editorView.textStorage?.appendAttributedString(attributedString)
self.editorView.textStorage?.endEditing()
}

Resources