Limit the amount of characters inserted into a UITextField [duplicate] - swift

This question already has answers here:
Set the maximum character length of a UITextField in Swift
(22 answers)
How to limit the textfield entry to 2 decimal places in swift 4?
(8 answers)
Closed 4 years ago.
How can I change a UITextField, that the User can just add one . and only two digits after the . -> Decimal Number with two digits after the poi^nt.

Use UITextFieldDelegate
// MARK:- TEXTFIELD DELEGATE
func textField(_ textField: UITextField,shouldChangeCharactersIn range: NSRange,replacementString string: String) -> Bool
{
let countdots = (txf_Amount.text?.components(separatedBy: ".").count)! - 1
if countdots > 0 && string == "."
{
return false
}
let MAX_BEFORE_DECIMAL_DIGITS = 7
let MAX_AFTER_DECIMAL_DIGITS = 3
let computationString = (textField.text! as NSString).replacingCharacters(in: range, with: string)
// Take number of digits present after the decimal point.
let arrayOfSubStrings = computationString.components(separatedBy: ".")
if arrayOfSubStrings.count == 1 && computationString.characters.count > MAX_BEFORE_DECIMAL_DIGITS {
return false
} else if arrayOfSubStrings.count == 2 {
let stringPostDecimal = arrayOfSubStrings[1]
return stringPostDecimal.characters.count <= MAX_AFTER_DECIMAL_DIGITS
}
return true
}

Related

How to create 15 digit length random string in Swift? [duplicate]

This question already has answers here:
Random Password Generator Swift 3?
(3 answers)
Closed 2 years ago.
In Javascript, Node.js I can generate with https://www.npmjs.com/package/uuid package a 15 digit length "random" string. Is it possible it with Swift?
Like this: 802128100247740
const uuidv4 = require("uuid/v4");
tempUserUuid = uuidv4();
Swift 5.0 introduced major improvements in dealing with random values and elements. The following code will help you
func randomString(length: Int) -> String {
let letters = "0123456789"
return String((0..<length).map{ _ in letters.randomElement()! })
}
label.text = randomString(length: 15)
The other answers generate a random number multiple times, but you only need to do it once.
import Foundation
extension String {
/// A leading-zero-padded padded random number.
/// - Returns: nil if digitCount is too big for `UInt` (You get 19 or fewer!)
static func randomNumber(digitCount: Int) -> Self? {
let digitCountDouble = Double(digitCount)
guard digitCountDouble < log10( Double(UInt.max) ) else {
return nil
}
let formatter = NumberFormatter()
formatter.minimumIntegerDigits = digitCount
let upperBound = pow(10, digitCountDouble)
return formatter.string(
for: UInt.random( in: 0..<UInt(upperBound) )
)!
}
}
func randomString(length: Int) -> String {
return (0..<length).map { _ in String(Int.random(in: 0...9)) }.joined()
}
func randomStringBuffer(length: Int) -> String {
var buffer = ""
(0..<length).forEach { _ in buffer += String(Int.random(in: 0...9)) }
return buffer
}
print(randomString(length: 15))
print(randomStringBuffer(length: 15))
first is compact, but second is more efficient, but in this situation (generating only 15 digits string) it doesn't matter, I think
UPD
I made a test, and it says that I was wrong. Seems first approach, with joined() is better
let a = Date().timeIntervalSince1970
print(a)
let g = randomString(length: 10000)
let b = Date().timeIntervalSince1970
print(b)
print(b - a)
let c = Date().timeIntervalSince1970
print(c)
let f = randomStringBuffer(length: 10000)
let d = Date().timeIntervalSince1970
print(d)
print(d - c)
1583933185.788064
1583933185.9271421
0.13907814025878906 // joined() version
1583933185.927207
1583933186.2418242
0.3146171569824219 // buffer version
UPD 2
Also made a public gist also with #deep-kakkar function.
As I can see, "joined()" method made it most efficient

Limit the number of characters in swift [duplicate]

This question already has answers here:
Setting maximum number of characters of `UITextView ` and `UITextField `
(10 answers)
Closed 3 years ago.
I have created the following code where I have an outlet name password, when the user enters a password, I seek to have a limit of more than 5 characters and less than 15. How can I impose this limit within this code?
guard let password = password.text, password.count > 6 else {
self.password.showError(true)
return
}
guard (password == confirmPassword.text) else {
self.confirmPassword.showError(true)
return
}
You can do
guard let password = password.text, password.count > 5 , password.count < 15 else {
self.password.showError(true)
return
}
or
guard (6...15).contains(password.text!.count) else {
self.password.showError(true)
return
}
Also you can use shouldChangeCharactersIn delegate method of the UITextField to limit the count check This

How do you split a string at every n-th character in Swift? [duplicate]

This question already has answers here:
How to split a string into substrings of equal length
(13 answers)
Closed 4 years ago.
Like the question says, if I have:
XQQ230IJFEKJLDSAIOUOIDSAUIFOPDSFE28
How can I split this string at every 8th character to get:
XQQ230IJ FEKJLDSA IOUOIDSA UIFOPDSA
Implement this function
extension String {
func inserting(separator: String, every n: Int) -> String {
var result: String = ""
let characters = Array(self.characters)
stride(from: 0, to: characters.count, by: n).forEach {
result += String(characters[$0..<min($0+n, characters.count)])
if $0+n < characters.count {
result += separator
}
}
return result
}
}
call it this way,
let str = "XQQ230IJFEKJLDSAIOUOIDSAUIFOPDSFE28"
let final = str.inserting(separator: " ", every: 8)
print(final)
Output will be like this,
XQQ230IJ FEKJLDSA IOUOIDSA UIFOPDSF E28
This will be generic solution if you want to add any character instead of space, it will work.

How to split or iterate over an Int without converting to String in Swift [duplicate]

This question already has answers here:
Break A Number Up To An Array of Individual Digits
(6 answers)
Closed 5 years ago.
I was wondering if there was a way in Swift to split an Int up into it's individual digits without converting it to a String. For example:
let x: Int = 12345
//Some way to loop/iterate over x's digits
//Then map each digit in x to it's String value
//Return "12345"
For a bit of background, I'm attempting to create my own method of converting an Int to a String without using the String description property or using String Interpolation.
I've found various articles on this site but all the ones I've been able to find either start with a String or end up using the String description property to convert the Int to a String.
Thanks.
Just keep dividing by 10 and take the remainder:
extension Int {
func digits() -> [Int] {
var digits: [Int] = []
var num = self
repeat {
digits.append(num % 10)
num /= 10
} while num != 0
return digits.reversed()
}
}
x.digits() // [1,2,3,4,5]
Note that this will return all negative digits if the value is negative. You could add a special case if you want to handle that differently. This return [0] for 0, which is probably what you want.
And because everyone like pure functional programming, you can do it that way too:
func digits() -> [Int] {
let partials = sequence(first: self) {
let p = $0 / 10
guard p != 0 else { return nil }
return p
}
return partials.reversed().map { $0 % 10 }
}
(But I'd probably just use the loop here. I find sequence too tricky to reason about in most cases.)
A recursive way...
extension Int {
func createDigitArray() -> [Int] {
if self < 10 {
return [self]
} else {
return (self / 10).createDigitArray() + [self % 10]
}
}
}
12345.createDigitArray() //->[1, 2, 3, 4, 5]
A very easy approach would be using this function:
func getDigits(of number: Int) -> [Int] {
var digits = [Int]()
var x = number
repeat{
digits.insert(abs(x % 10), at: 0)
x/=10
} while x != 0
return digits
}
And using it like this:
getDigits(of: 97531) // [9,7,5,3,1]
getDigits(of: -97531) // [9,7,5,3,1]
As you can see, for a negative number you will receive the array of its digits, but at their absolute value (e.g.: -9 => 9 and -99982 => 99982)
Hope it helps!

xcode swift - formatting text as phone number [duplicate]

This question already has answers here:
UITextField for Phone Number
(25 answers)
Closed 8 years ago.
I'm creating an iPhone app using Swift. I'm trying to setup a textfield in which the user can enter a phone number that automatically becomes formatted EXACTLY like it does in the built-in Contacts app as it is typed. I'm hoping xcode has built-in methods for doing this.
As an alternative, I created my own code that would add and delete brackets, dashes, etc as the user types and backspaces, but this quickly became problematic if the user was to move the curser away from the end of the entered text. In the Contacts app, if the cursor is moved just after a bracket and the user hits backspace, it deletes not just the bracket but rather the number preceding it. I'm not sure if this is done with some built-in formatting method or if perhaps there is code that replicates the text shown with brackets, dashes, etc removed and reads the position of the cursor, then calculates what the new string should be, and adds new brackets, dashes, etc.
Specifically, I'd like to know:
1) Is there a built-in method to format text to look like a phone number exactly as is done in the Contacts app?
2) If there is no built-in method, can someone tell me how I can have Swift read in the cursor position?
Thanks!
There is no built-in way to do this. Here's one implementation that uses the UITextField's shouldChangeCharactersInRange method:
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool
{
if textField == phoneTextField
{
var newString = (textField.text as NSString).stringByReplacingCharactersInRange(range, withString: string)
var components = newString.componentsSeparatedByCharactersInSet(NSCharacterSet.decimalDigitCharacterSet().invertedSet)
var decimalString = "".join(components) as NSString
var length = decimalString.length
var hasLeadingOne = length > 0 && decimalString.characterAtIndex(0) == (1 as unichar)
if length == 0 || (length > 10 && !hasLeadingOne) || length > 11
{
var newLength = (textField.text as NSString).length + (string as NSString).length - range.length as Int
return (newLength > 10) ? false : true
}
var index = 0 as Int
var formattedString = NSMutableString()
if hasLeadingOne
{
formattedString.appendString("1 ")
index += 1
}
if (length - index) > 3
{
var areaCode = decimalString.substringWithRange(NSMakeRange(index, 3))
formattedString.appendFormat("(%#)", areaCode)
index += 3
}
if length - index > 3
{
var prefix = decimalString.substringWithRange(NSMakeRange(index, 3))
formattedString.appendFormat("%#-", prefix)
index += 3
}
var remainder = decimalString.substringFromIndex(index)
formattedString.appendString(remainder)
textField.text = formattedString
return false
}
else
{
return true
}
}
As previously answered in this thread: UITextField for Phone Number