ava*_*ava 2 uitextfield ios swift
我有一个textfield最大字符范围16,每4个字符后,我想添加减去字符或空格然后写其余的字符像这样的样本5022-2222-2222-2222.有我的代码,但这不起作用,怎么办呢?
if textField.text?.characters.count == 5 {
let l = textField.text?.characters.count
let attributedString = NSMutableAttributedString(string: cartNumberTextField.text!)
attributedString.addAttribute(NSKernAttributeName, value: CGFloat(4.0), range: NSRange(location: l!, length: 4))
cartNumberTextField.attributedText = attributedString
}
else if textField.text?.characters.count == 9 {
let l = textField.text?.characters.count
let attributedString = NSMutableAttributedString(string: cartNumberTextField.text!)
attributedString.addAttribute(NSKernAttributeName, value: CGFloat(4.0), range: NSRange(location: l!, length: 4))
cartNumberTextField.attributedText = attributedString
}
else if textField.text?.characters.count == 13 {
let l = textField.text?.characters.count
let attributedString = NSMutableAttributedString(string: cartNumberTextField.text!)
attributedString.addAttribute(NSKernAttributeName, value: CGFloat(4.0), range: NSRange(location: l!, length: 4))
cartNumberTextField.attributedText = attributedString
}
Run Code Online (Sandbox Code Playgroud)
我在UITextField shouldChangeCharactersIn范围方法中添加此代码.
我们可以通过实施斯威夫特3版本的启动chunk(n:)方法(对于Collectionoisdk的"S):■ SwiftSequence:
/* Swift 3 version of Github use oisdk:s SwiftSequence's 'chunk' method:
https://github.com/oisdk/SwiftSequence/blob/master/Sources/ChunkWindowSplit.swift */
extension Collection {
public func chunk(n: IndexDistance) -> [SubSequence] {
var res: [SubSequence] = []
var i = startIndex
var j: Index
while i != endIndex {
j = index(i, offsetBy: n, limitedBy: endIndex) ?? endIndex
res.append(self[i..<j])
i = j
}
return res
}
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,实现自定义格式是一个简单的例子,创建4个字符的块并通过" - "连接它们:
func customStringFormatting(of str: String) -> String {
return str.characters.chunk(n: 4)
.map{ String($0) }.joined(separator: "-")
}
Run Code Online (Sandbox Code Playgroud)
用法示例:
print(customStringFormatting(of: "5022222222222222")) // 5022-2222-2222-2222
print(customStringFormatting(of: "50222222222222")) // 5022-2222-2222-22
print(customStringFormatting(of: "5022222")) // 5022-222
Run Code Online (Sandbox Code Playgroud)
如果要在textField(_:shouldChangeCharactersIn:replacementString:)方法中使用UITextFieldDelegate,我们可能希望在customStringFormatting(of:)方法方法中过滤掉现有的分隔符,并将其作为String扩展实现:
extension String {
func chunkFormatted(withChunkSize chunkSize: Int = 4,
withSeparator separator: Character = "-") -> String {
return characters.filter { $0 != separator }.chunk(n: chunkSize)
.map{ String($0) }.joined(separator: String(separator))
}
}
Run Code Online (Sandbox Code Playgroud)
并实现文本字段的受控更新,例如如下:
let maxNumberOfCharacters = 16
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
// only allow numerical characters
guard string.characters.flatMap({ Int(String($0)) }).count ==
string.characters.count else { return false }
let text = textField.text ?? ""
if string.characters.count == 0 {
textField.text = String(text.characters.dropLast()).chunkFormatted()
}
else {
let newText = String((text + string).characters
.filter({ $0 != "-" }).prefix(maxNumberOfCharacters))
textField.text = newText.chunkFormatted()
}
return false
}
Run Code Online (Sandbox Code Playgroud)
上面的最后一部分将截断用户可能粘贴的字符串(假设它都是数字),例如
// current
1234-1234-123
// user paste:
777777777
/* ^^^^ will not be included due to truncation */
// will result in
1234-1234-1237-7777
Run Code Online (Sandbox Code Playgroud)
shouldChangeCharactersIn像这样使用.
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
if [6, 11, 16].contains(textField.text?.count ?? 0) && string.isEmpty {
textField.text = String(textField.text!.dropLast())
return true
}
let text = NSString(string: textField.text ?? "").replacingCharacters(in: range, with: string).replacingOccurrences(of: "-", with: "")
if text.count >= 4 && text.count <= 16 {
var newString = ""
for i in stride(from: 0, to: text.count, by: 4) {
let upperBoundIndex = i + 4
let lowerBound = String.Index.init(encodedOffset: i)
let upperBound = String.Index.init(encodedOffset: upperBoundIndex)
if upperBoundIndex <= text.count {
newString += String(text[lowerBound..<upperBound]) + "-"
if newString.count > 19 {
newString = String(newString.dropLast())
}
}
else if i <= text.count {
newString += String(text[lowerBound...])
}
}
textField.text = newString
return false
}
if text.count > 16 {
return false
}
return true
}
Run Code Online (Sandbox Code Playgroud)
注意:我已经习惯了- (Hyphen)你可以简单地替换它,Space如果你想要Space而不是- (Hyphen).
编辑:代码被编辑为最新的swift 4.*,对于较旧的swift版本,请检查编辑历史记录.
| 归档时间: |
|
| 查看次数: |
6669 次 |
| 最近记录: |