我正在输入信用卡信息,我希望有效期限最多为5个字符4个数字,并且在前两个字符后自动输入“/”,即在键入01后自动输入的01/17,并且只允许两个字符“17”。
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool
{
if textField == expire{
}
return true
}
答案 0 :(得分:6)
Swift 4解决方案,基于@Jigar的回答:
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
if range.length > 0 {
return true
}
if string == "" {
return false
}
if range.location > 4 {
return false
}
var originalText = textField.text
let replacementText = string.replacingOccurrences(of: " ", with: "")
//Verify entered text is a numeric value
if !CharacterSet.decimalDigits.isSuperset(of: CharacterSet(charactersIn: replacementText)) {
return false
}
//Put / after 2 digit
if range.location == 2 {
originalText?.append("/")
textField.text = originalText
}
return true
}
答案 1 :(得分:4)
尝试这样,它在我的最后工作。
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool
{
//Range.Lenth will greater than 0 if user is deleting text - Allow it to replce
if range.length > 0
{
if range.location == 3 {
var originalText = textField.text
originalText = originalText?.replacingOccurrences(of: "/", with: "")
textField.text = originalText
}
return true
}
//Dont allow empty strings
if string == " "
{
return false
}
//Check for max length including the spacers we added
if range.location >= 5
{
return false
}
var originalText = textField.text
let replacementText = string.stringByReplacingOccurrencesOfString(" ", withString: "")
//Verify entered text is a numeric value
let digits = NSCharacterSet.decimalDigitCharacterSet()
for char in replacementText.unicodeScalars
{
if !digits.longCharacterIsMember(char.value)
{
return false
}
}
//Put / space after 2 digit
if range.location == 2
{
originalText?.appendContentsOf("/")
textField.text = originalText
}
return true
}
希望这对你有所帮助。
答案 2 :(得分:1)
答案并不能很好地处理退格。这是我的解决方案(不幸的是在Objective-C中实现):
@interface CreditCardViewController()
<UITextFieldDelegate>
@property (weak,nonatomic) IBOutlet UITextField * cardExpirationTextField;
@property (strong,nonatomic) NSString * previousExpiryDate;
@property (strong,nonatomic) UITextRange * previousExpiryDateSelection;
@property (assign,readonly,nonatomic) NSString * minYearLast2Digits;
@end
@implementation CreditCardViewController
-(instancetype) init
{
self = [super initWithNibName:NSStringFromClass([CreditCardViewController class]) bundle:nil];
if(self){
_minYearLast2Digits = [[[NSNumber numberWithInteger:[NSDate date].year] stringValue] substringFromIndex:2];
}
return self;
}
-(void) viewDidLoad
{
[super viewDidLoad];
[self setupView]
}
-(void) setupView
{
self.cardExpirationTextField.delegate = self;
[self.cardExpirationTextField addTarget:self
action:@selector(reformatCardExpiryDate:)
forControlEvents:UIControlEventEditingChanged];
}
-(BOOL) textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
NSUInteger newLength = [textField.text length] + [string length] - range.length;
if(textField == self.cardExpirationTextField){
self.previousExpiryDate = textField.text;
self.previousExpiryDateSelection = textField.selectedTextRange;
return newLength <= 5;
}
return YES;
}
-(void) reformatCardExpiryDate:(UITextField*) textField
{
const BOOL isErasing = self.previousExpiryDate.length > textField.text.length;
BOOL invalid = [textField.text length] > 5;
if([textField.text length] > 0){
unichar firstChar = [textField.text characterAtIndex:0];
invalid |= (firstChar > '1');
}
if([textField.text length] > 1){
unichar firstChar = [textField.text characterAtIndex:0];
unichar secondChar = [textField.text characterAtIndex:1];
invalid |= (firstChar == '1' && secondChar > '2');
}
if([textField.text length] > 2){
invalid |= [textField.text characterAtIndex:2] != '/';
}
if([textField.text length] > 3){
unichar yearFirstDigit = [textField.text characterAtIndex:3];
unichar minYearFirstDigit = [self.minYearLast2Digits characterAtIndex:0];
invalid |= yearFirstDigit < minYearFirstDigit;
}
if([textField.text length] > 4){
NSString* yearLastTwoDigits = [textField.text substringFromIndex:3];
invalid |= [yearLastTwoDigits compare:_minYearLast2Digits] == NSOrderedAscending;
}
if(invalid){
[textField setText:self.previousExpiryDate];
textField.selectedTextRange = self.previousExpiryDateSelection;
return;
}
if(!isErasing && textField.text.length == 2){
textField.text = [textField.text stringByAppendingString:@"/"];
UITextPosition *targetPosition =
[textField positionFromPosition:[textField beginningOfDocument]
offset:textField.text.length];
[textField setSelectedTextRange:
[textField textRangeFromPosition:targetPosition
toPosition:targetPosition]
];
}
}
@end
答案 3 :(得分:0)
试试这段代码:
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool
{
let num:NSString = textField.text! ;
if num.length == 1
{
textField.text = NSString(format:"%@%@/",num,string) as String
return false;
}
if num.length >= 5 {
// allows only two more characters "17".
return false;
}
return true;
}
答案 4 :(得分:-1)
我刚刚对此进行了编码,对我来说很好用。
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
var index = range.lowerBound
let fecha = textField.text!
if string == "" {
var array = Array(fecha)
array.remove(at: index)
if array.count > 2 {
if !array.contains("/"){
array.insert("/", at: 2)
}
}
textField.text = String(array)
let cursorPosition = textField.position(from: textField.beginningOfDocument, offset: index)!
textField.selectedTextRange = textField.textRange(from: cursorPosition, to: cursorPosition)
}else{
let expiracion = fecha.replacingOccurrences(of: "/", with: "")
if fecha != expiracion{
if index > 1 {
index = range.lowerBound - 1
}
}
var array = Array(expiracion)
if array.count < 4 {
print("index: \(index) - \(array)")
let newChar = Character(string)
array.insert(newChar, at: index)
print("new array: ", array)
if array.count > 2 {
array.insert("/", at: 2)
}
textField.text = String(array)
index = index > 1 ? index + 2 : index + 1
let cursorPosition = textField.position(from: textField.beginningOfDocument, offset: index)!
textField.selectedTextRange = textField.textRange(from: cursorPosition, to: cursorPosition)
}
}
return false
}