CAN*_*CAN 27 string string-formatting uitextfield ios swift
一旦用户开始在这种格式类型中输入电话号码,我就会格式化我的文本文本,0 (555) 444 66 77
并且它工作正常但是一旦我从服务器获得号码,我就这样得到它05554446677
所以请你告诉我如何编辑它一旦我从服务器上获取相同的格式?
我开始输入后的代码:
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
if textField == phoneNumberTextField{
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 > 11 && !hasLeadingOne) || length > 12{
var newLength = (textField.text as NSString).length + (string as NSString).length - range.length as Int
return (newLength > 11) ? false : true
}
var index = 0 as Int
var formattedString = NSMutableString()
if hasLeadingOne{
formattedString.appendString("1 ")
index += 1
}
if (length - index) > 1{
var zeroNumber = decimalString.substringWithRange(NSMakeRange(index, 1))
formattedString.appendFormat("%@ ", zeroNumber)
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
}
if (length - index) > 3{
var prefix = decimalString.substringWithRange(NSMakeRange(index, 2))
formattedString.appendFormat("%@ ", prefix)
index += 2
}
var remainder = decimalString.substringFromIndex(index)
formattedString.appendString(remainder)
textField.text = formattedString as String
return false
}else{
return true
}
}
Run Code Online (Sandbox Code Playgroud)
Rom*_*pov 52
func formattedNumber(number: String) -> String {
let cleanPhoneNumber = number.components(separatedBy: CharacterSet.decimalDigits.inverted).joined()
let mask = "+X (XXX) XXX-XXXX"
var result = ""
var index = cleanPhoneNumber.startIndex
for ch in mask where index < cleanPhoneNumber.endIndex {
if ch == "X" {
result.append(cleanPhoneNumber[index])
index = cleanPhoneNumber.index(after: index)
} else {
result.append(ch)
}
}
return result
}
Run Code Online (Sandbox Code Playgroud)
但是如果字符串字符大于或等于11,则它不起作用
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
guard let text = textField.text else { return false }
let newString = (text as NSString).replacingCharacters(in: range, with: string)
textField.text = formattedNumber(number: newString)
return false
}
Run Code Online (Sandbox Code Playgroud)
从UITextField委托方法调用上面的函数:
"" => ""
"0" => "+0"
"412" => "+4 (12"
"12345678901" => "+1 (234) 567-8901"
"a1_b2-c3=d4 e5&f6|g7?h8" => "+1 (234) 567-8"
Run Code Online (Sandbox Code Playgroud)
所以,这样做会更好.
func formattedNumber(number: String) -> String {
let cleanPhoneNumber = number.components(separatedBy: CharacterSet.decimalDigits.inverted).joined()
let mask = "+X (XXX) XXX-XXXX"
var result = ""
var index = cleanPhoneNumber.startIndex
for ch in mask where index < cleanPhoneNumber.endIndex {
if ch == "X" {
result.append(cleanPhoneNumber[index])
index = cleanPhoneNumber.index(after: index)
} else {
result.append(ch)
}
}
return result
}
Run Code Online (Sandbox Code Playgroud)
Mob*_*Dan 38
此解决方案在应用格式之前删除所有非数字字符.nil
如果无法根据假设格式化源电话号码,则返回.
Swift 4解决方案考虑了CharacterView的弃用和Sting成为CharacterView的字符集合.
import Foundation
func format(phoneNumber sourcePhoneNumber: String) -> String? {
// Remove any character that is not a number
let numbersOnly = sourcePhoneNumber.components(separatedBy: CharacterSet.decimalDigits.inverted).joined()
let length = numbersOnly.count
let hasLeadingOne = numbersOnly.hasPrefix("1")
// Check for supported phone number length
guard length == 7 || (length == 10 && !hasLeadingOne) || (length == 11 && hasLeadingOne) else {
return nil
}
let hasAreaCode = (length >= 10)
var sourceIndex = 0
// Leading 1
var leadingOne = ""
if hasLeadingOne {
leadingOne = "1 "
sourceIndex += 1
}
// Area code
var areaCode = ""
if hasAreaCode {
let areaCodeLength = 3
guard let areaCodeSubstring = numbersOnly.substring(start: sourceIndex, offsetBy: areaCodeLength) else {
return nil
}
areaCode = String(format: "(%@) ", areaCodeSubstring)
sourceIndex += areaCodeLength
}
// Prefix, 3 characters
let prefixLength = 3
guard let prefix = numbersOnly.substring(start: sourceIndex, offsetBy: prefixLength) else {
return nil
}
sourceIndex += prefixLength
// Suffix, 4 characters
let suffixLength = 4
guard let suffix = numbersOnly.substring(start: sourceIndex, offsetBy: suffixLength) else {
return nil
}
return leadingOne + areaCode + prefix + "-" + suffix
}
extension String {
/// This method makes it easier extract a substring by character index where a character is viewed as a human-readable character (grapheme cluster).
internal func substring(start: Int, offsetBy: Int) -> String? {
guard let substringStartIndex = self.index(startIndex, offsetBy: start, limitedBy: endIndex) else {
return nil
}
guard let substringEndIndex = self.index(startIndex, offsetBy: start + offsetBy, limitedBy: endIndex) else {
return nil
}
return String(self[substringStartIndex ..< substringEndIndex])
}
}
Run Code Online (Sandbox Code Playgroud)
import Foundation
func format(phoneNumber sourcePhoneNumber: String) -> String? {
// Remove any character that is not a number
let numbersOnly = sourcePhoneNumber.components(separatedBy: CharacterSet.decimalDigits.inverted).joined()
let length = numbersOnly.characters.count
let hasLeadingOne = numbersOnly.hasPrefix("1")
// Check for supported phone number length
guard length == 7 || (length == 10 && !hasLeadingOne) || (length == 11 && hasLeadingOne) else {
return nil
}
let hasAreaCode = (length >= 10)
var sourceIndex = 0
// Leading 1
var leadingOne = ""
if hasLeadingOne {
leadingOne = "1 "
sourceIndex += 1
}
// Area code
var areaCode = ""
if hasAreaCode {
let areaCodeLength = 3
guard let areaCodeSubstring = numbersOnly.characters.substring(start: sourceIndex, offsetBy: areaCodeLength) else {
return nil
}
areaCode = String(format: "(%@) ", areaCodeSubstring)
sourceIndex += areaCodeLength
}
// Prefix, 3 characters
let prefixLength = 3
guard let prefix = numbersOnly.characters.substring(start: sourceIndex, offsetBy: prefixLength) else {
return nil
}
sourceIndex += prefixLength
// Suffix, 4 characters
let suffixLength = 4
guard let suffix = numbersOnly.characters.substring(start: sourceIndex, offsetBy: suffixLength) else {
return nil
}
return leadingOne + areaCode + prefix + "-" + suffix
}
extension String.CharacterView {
/// This method makes it easier extract a substring by character index where a character is viewed as a human-readable character (grapheme cluster).
internal func substring(start: Int, offsetBy: Int) -> String? {
guard let substringStartIndex = self.index(startIndex, offsetBy: start, limitedBy: endIndex) else {
return nil
}
guard let substringEndIndex = self.index(startIndex, offsetBy: start + offsetBy, limitedBy: endIndex) else {
return nil
}
return String(self[substringStartIndex ..< substringEndIndex])
}
}
Run Code Online (Sandbox Code Playgroud)
func testFormat(sourcePhoneNumber: String) -> String {
if let formattedPhoneNumber = format(phoneNumber: sourcePhoneNumber) {
return "'\(sourcePhoneNumber)' => '\(formattedPhoneNumber)'"
}
else {
return "'\(sourcePhoneNumber)' => nil"
}
}
print(testFormat(sourcePhoneNumber: "1 800 222 3333"))
print(testFormat(sourcePhoneNumber: "18002223333"))
print(testFormat(sourcePhoneNumber: "8002223333"))
print(testFormat(sourcePhoneNumber: "2223333"))
print(testFormat(sourcePhoneNumber: "18002223333444"))
print(testFormat(sourcePhoneNumber: "Letters8002223333"))
print(testFormat(sourcePhoneNumber: "1112223333"))
Run Code Online (Sandbox Code Playgroud)
'1 800 222 3333' => '1 (800) 222-3333'
'18002223333' => '1 (800) 222-3333'
'8002223333' => '(800) 222-3333'
'2223333' => '222-3333'
'18002223333444' => nil
'Letters8002223333' => '(800) 222-3333'
'1112223333' => nil
Run Code Online (Sandbox Code Playgroud)
小智 20
真正简单的解决方案:
extension String {
func applyPatternOnNumbers(pattern: String, replacmentCharacter: Character) -> String {
var pureNumber = self.replacingOccurrences( of: "[^0-9]", with: "", options: .regularExpression)
for index in 0 ..< pattern.count {
guard index < pureNumber.count else { return pureNumber }
let stringIndex = String.Index(encodedOffset: index)
let patternCharacter = pattern[stringIndex]
guard patternCharacter != replacmentCharacter else { continue }
pureNumber.insert(patternCharacter, at: stringIndex)
}
return pureNumber
}
}
Run Code Online (Sandbox Code Playgroud)
用法:
guard let text = textField.text else { return }
textField.text = text.applyPatternOnNumbers(pattern: "+# (###) ###-####", replacmentCharacter: "#")
Run Code Online (Sandbox Code Playgroud)
Avt*_*Avt 12
在String中使用字符进行操作并不是非常简单.你需要以下:
斯威夫特2.1
let s = "05554446677"
let s2 = String(format: "%@ (%@) %@ %@ %@", s.substringToIndex(s.startIndex.advancedBy(1)),
s.substringWithRange(s.startIndex.advancedBy(1) ... s.startIndex.advancedBy(3)),
s.substringWithRange(s.startIndex.advancedBy(4) ... s.startIndex.advancedBy(6)),
s.substringWithRange(s.startIndex.advancedBy(7) ... s.startIndex.advancedBy(8)),
s.substringWithRange(s.startIndex.advancedBy(9) ... s.startIndex.advancedBy(10))
)
Run Code Online (Sandbox Code Playgroud)
Swift 2.0
let s = "05554446677"
let s2 = String(format: "%@ (%@) %@ %@ %@", s.substringToIndex(advance(s.startIndex, 1)),
s.substringWithRange(advance(s.startIndex, 1) ... advance(s.startIndex, 3)),
s.substringWithRange(advance(s.startIndex, 4) ... advance(s.startIndex, 6)),
s.substringWithRange(advance(s.startIndex, 7) ... advance(s.startIndex, 8)),
s.substringWithRange(advance(s.startIndex, 9) ... advance(s.startIndex, 10))
)
Run Code Online (Sandbox Code Playgroud)
代码将打印
0 (555) 444 66 77
你可以使用这个库https://github.com/luximetr/AnyFormatKit
例子
let phoneFormatter = DefaultTextFormatter(textPattern: "### (###) ###-##-##")
phoneFormatter.format("+123456789012") // +12 (345) 678-90-12
Run Code Online (Sandbox Code Playgroud)
使用起来非常简单。
斯威夫特 4
创建此函数并调用文本字段事件 Editing Changed
private func formatPhone(_ number: String) -> String {
let cleanNumber = number.components(separatedBy: CharacterSet.decimalDigits.inverted).joined()
let format: [Character] = ["X", "X", "X", "-", "X", "X", "X", "-", "X", "X", "X", "X"]
var result = ""
var index = cleanNumber.startIndex
for ch in format {
if index == cleanNumber.endIndex {
break
}
if ch == "X" {
result.append(cleanNumber[index])
index = cleanNumber.index(after: index)
} else {
result.append(ch)
}
}
return result
}
Run Code Online (Sandbox Code Playgroud)
小智 5
Swift 5.1 更新 ????? ?????????很好的解决方案
extension String {
func applyPatternOnNumbers(pattern: String, replacmentCharacter: Character) -> String {
var pureNumber = self.replacingOccurrences( of: "[^0-9]", with: "", options: .regularExpression)
for index in 0 ..< pattern.count {
guard index < pureNumber.count else { return pureNumber }
let stringIndex = String.Index(utf16Offset: index, in: self)
let patternCharacter = pattern[stringIndex]
guard patternCharacter != replacmentCharacter else { continue }
pureNumber.insert(patternCharacter, at: stringIndex)
}
return pureNumber
}
}
Run Code Online (Sandbox Code Playgroud)
用法:
let formattedText = text.applyPatternOnNumbers(pattern: "+# (###) ###-####", replacmentCharacter: "#")
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
38114 次 |
最近记录: |