Phát hiện backspace trong UITextField trống


126

Có cách nào để phát hiện khi nhấn phím Backspace/ Deletephím trong bàn phím iPhone UITextFieldkhông? Tôi muốn biết khi nào chỉ Backspaceđược nhấn nếu UITextFieldtrống.


Dựa trên đề xuất từ ​​@Alex Reynold trong một nhận xét, tôi đã thêm đoạn mã sau trong khi tạo trường văn bản của mình:

[[NSNotificationCenter defaultCenter] addObserver:self
          selector:@selector(handleTextFieldChanged:)
              name:UITextFieldTextDidChangeNotification
            object:searchTextField];

Thông báo này được nhận ( handleTextFieldChangedchức năng được gọi), nhưng vẫn không phải khi tôi nhấn Backspacephím trong trường trống. Có ý kiến ​​gì không?


Dường như có một số nhầm lẫn xung quanh câu hỏi này. Tôi muốn nhận thông báo khi Backspacenhấn phím. Đó là nó. Nhưng giải pháp cũng phải hoạt động khi UITextFieldđã trống.


Tôi nghĩ bạn có thể có nghĩa là "chỉ khi UITextField trống" chứ không phải "chỉ khi bàn phím trống" ...?
Steve Harrison

@Steve Harrison: cảm ơn. Cập nhật mà.
marcc

Tôi đang cố gắng làm một cái gì đó tương tự, sau đó bạn đã nhận được giải pháp gì? Những gì tôi đang làm là một trường văn bản trong chế độ xem cuộn, khi tôi nhập một số văn bản, các đề xuất được hiển thị và khi tôi nhấp vào một, một đối tượng nhãn được đặt ở bên trái của trường văn bản. Cảm ơn trước: D
Dough

Giải pháp 2011/11 cho UITextField trống bằng cách sử dụng thủ thuật thời gian chạy: bjhomer.blogspot.com/2011/11/ Mạnh
Jano

4
Vô lý dài cho một cái gì đó tầm thường. Điều này không nên khó khăn.
Adam Chờ đợi

Câu trả lời:


36

Đây có thể là một cú sút xa nhưng nó có thể làm việc. Hãy thử đặt văn bản của trường văn bản thành ký tự không gian có chiều rộng bằng không \u200B. Khi nhấn phím lùi trên trường văn bản có vẻ trống, nó sẽ thực sự xóa không gian của bạn. Sau đó, bạn có thể chỉ cần đặt lại không gian.

Có thể không hoạt động nếu người dùng quản lý để di chuyển dấu mũ sang bên trái của không gian.


3
@Andrew, đây là cách tiếp cận tôi quyết định thực hiện. Phải mất một chút mã, nhưng nó chắc chắn có hiệu quả. Cảm ơn sự giúp đỡ thay vì cố gắng nói với tôi rằng tôi đang làm gì đó sai.
marcc

2
Kỹ thuật này có thể làm việc trên iPhone> 3.1.3, nhưng nó hacky và có thể phá vỡ trên các phiên bản trong tương lai, vv Tôi nghĩ rằng tôi đã tìm thấy một trình dọn dẹp, nhiều giải pháp ổn định cho làm thế nào để phát hiện một xóa key bàn phím bấm trên iPhone / iOS .
ma11hew28

6
Tôi có thể xác nhận rằng xóa không được phát hiện nếu người dùng quản lý để di chuyển con trỏ sang bên trái của không gian. Nếu bạn có thể tìm ra cách để khắc phục điều đó, thì bạn cũng nên phân lớp UITextFieldvà thực hiện canPerformAction:withSender:để return NOcho select:selectAll:hành động khi văn bản bằng chuỗi @"\u200B".
ma11hew28

2
Vấn đề là điều này không hoạt động cho các trường kiểm tra an toàn. Bất kỳ ý tưởng làm thế nào để xử lý đó?
Kyle Clegg

7
Xin lỗi, nhưng ý tưởng này là xấu. Đó là hacky đáng kinh ngạc và không nên là câu trả lời được chấp nhận với 30 upvote. Thay vào đó, tôi sẽ phân lớp UITextField, giống như một số bình luận khác đã đề cập.
Brian Sachetta

155

Swift 4:


Phân lớp UITextField:

// MyTextField.swift
import UIKit

protocol MyTextFieldDelegate: AnyObject {
    func textFieldDidDelete()
}

class MyTextField: UITextField {

    weak var myDelegate: MyTextFieldDelegate?

    override func deleteBackward() {
        super.deleteBackward()
        myDelegate?.textFieldDidDelete()
    }

}

Thực hiện:

// ViewController.swift

import UIKit

class ViewController: UIViewController, MyTextFieldDelegate {

    override func viewDidLoad() {
        super.viewDidLoad()

        // initialize textField
        let input = MyTextField(frame: CGRect(x: 50, y: 50, width: 150, height: 40))

        // set viewController as "myDelegate"
        input.myDelegate = self

        // add textField to view
        view.addSubview(input)

        // focus the text field
        input.becomeFirstResponder()
    }

    func textFieldDidDelete() {
        print("delete")
    }

}

Mục tiêu-C:


Phân lớp UITextField:

//Header
//MyTextField.h

//create delegate protocol
@protocol MyTextFieldDelegate <NSObject>
@optional
- (void)textFieldDidDelete;
@end

@interface MyTextField : UITextField<UIKeyInput>

//create "myDelegate"
@property (nonatomic, assign) id<MyTextFieldDelegate> myDelegate;
@end

//Implementation
#import "MyTextField.h"

@implementation MyTextField

- (void)deleteBackward {
    [super deleteBackward];

    if ([_myDelegate respondsToSelector:@selector(textFieldDidDelete)]){
        [_myDelegate textFieldDidDelete];
    }
}

@end

Bây giờ chỉ cần thêm MyTextFieldDelegate vào của bạn UIViewControllervà đặt UITextFields myDelegate của bạn thành self:

//View Controller Header
#import "MyTextField.h"

//add "MyTextFieldDelegate" to you view controller
@interface ViewController : UIViewController <MyTextFieldDelegate>
@end

//View Controller Implementation
- (void)viewDidLoad {
    //initialize your text field
    MyTextField *input = 
     [[MyTextField alloc] initWithFrame:CGRectMake(0, 0, 70, 30)];

    //set your view controller as "myDelegate"
    input.myDelegate = self;

    //add your text field to the view
    [self.view addSubview:input];
}

//MyTextField Delegate
- (void)textFieldDidDelete {
    NSLog(@"delete");
}

9
Đây là giải pháp tốt nhất. Câu trả lời được chấp nhận là một hack. Mục tiêu C dựa trên phân loại phụ và giải pháp này sử dụng nó đúng cách để giải quyết vấn đề.
TJ

Điều gì sẽ xảy ra với các phương thức đại biểu hiện có của tôi trong ViewController lớp nếu tôi đặt đại biểu của trường văn bản của mình thành lớp con UITextFieldthay vìUIViewController
rohan-patel

4
Điều này dường như không hoạt động trong ios8 ngay bây giờ, do có vẻ như là một lỗi của Apple: devforums.apple.com/message/1045312#1045312
chug2k

1
Tôi đã sử dụng một giải pháp khắc phục cho lỗi ios8 như trong câu trả lời của tôi và nó đã hoạt động. Nó có thể hữu ích cho những người đang tìm kiếm một giải pháp.
furkan3ayraktar

1
deleteBackward()sẽ không được gọi nếu bạn return falsetham giatextField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool
igrrik

41

Cập nhật: Xem câu trả lời của JacobCaraballo để biết ví dụ ghi đè -[UITextField deleteBackward].

Kiểm tra UITextInput, đặc biệt là UIKeyInputcó một deleteBackwardphương pháp đại biểu rằng luôn luôn được gọi khi phím delete được nhấn. Nếu bạn đang làm một cái gì đó đơn giản, thì bạn có thể xem xét chỉ phân lớp UILabelvà làm cho nó phù hợp với UIKeyInputgiao thức, như được thực hiện bởi SimpleTextInputVí dụ UIKeyInput iPhone này . Lưu ý: UITextInputvà họ hàng của nó (bao gồm UIKeyInput) chỉ khả dụng trong iOS 3.2 trở lên.


2
Đây là câu trả lời đúng. Nó không hack và rất đơn giản với một lớp con nhanh chóng của UITextField.
Sam

Chỉ cần phát hiện câu trả lời của Jacob dưới đây. Nó đưa ra một ví dụ chi tiết về điều này.
Sam

Điều đáng chú ý là câu trả lời này không hoạt động trong iOS 5. Nếu trường văn bản trống, nhấn backspace không gọi phương thức này.
jfeldman

31

Mã như sau:

@interface MyTextField : UITextField
@end

@implementation MyTextField

- (void)deleteBackward
{
    [super deleteBackward];

    //At here, you can handle backspace key pressed event even the text field is empty
}

@end

Cuối cùng, đừng quên thay đổi thuộc tính Lớp tùy chỉnh của Trường văn bản thành "MyTextField"


5
Đây phải là câu trả lời được chấp nhận. Sạch sẽ, và thực sự trả lời câu hỏi.
Ryan Romanchuk

1
Nó trả lời câu hỏi ... Miễn là bạn đang nhắm mục tiêu iOS 6.0+. Trên iOS 5, không may đơn giản là không bao giờ được gọi trên lớp con của bạn.
BJ Homer

2
BJ Homer, 93% thiết bị có trên iOS 6, do đó, việc không nhắm mục tiêu iOS 5 thường không phải là vấn đề lớn.
Jonathan.

2
Tôi rất vui vì tôi tiếp tục cuộn xuống đủ để tìm thấy điều này. 100% cách đúng đắn để làm điều này ngay hôm nay trong iOS 7.
MusiGenesis

Tôi đã thấy rất nhiều câu trả lời khác cho câu hỏi này chỉ là cách giải quyết, và hầu như không có câu trả lời nào trong số đó giải quyết tình huống phím phím lùi được nhấn trong trường trống. Điều này tuy nhiên là hoàn hảo, và một cách thực sự sạch sẽ để làm điều đó.
Christopher Hannah

19

Thực hiện Swift:

import UIKit

protocol PinTexFieldDelegate : UITextFieldDelegate {
    func didPressBackspace(textField : PinTextField)
}

class PinTextField: UITextField {

    override func deleteBackward() {
        super.deleteBackward()

        // If conforming to our extension protocol
        if let pinDelegate = self.delegate as? PinTexFieldDelegate {
            pinDelegate.didPressBackspace(self)
        }
    }
}

Cảm ơn, tôi có thể biết phương pháp này được đề xuất bởi apple hoặc nó là hack. nó dường như không có giấy tờ cho trường văn bản.
kalpesh jetani

Làm việc cho tôi với một textView. cảm ơn vì đã chia sẻ;)
Edouard Barbier

Làm việc cho tôi khi trường văn bản trống và không gian trở lại được nhấp.
Ramakrishna

17

Tôi đã thành lập cách khác dễ dàng hơn subclassgiải pháp. Ngay cả một chút lạ của nó nhưng nó hoạt động ok.

- (BOOL)textView:(UITextView *)textView 
        shouldChangeTextInRange:(NSRange)range 
        replacementText:(NSString *)text
{
    const char * _char = [text cStringUsingEncoding:NSUTF8StringEncoding];
    int isBackSpace = strcmp(_char, "\b");

    if (isBackSpace == -8) {
       // is backspace
    }

    return YES;
}

Hơi lạ một chút vì kết quả so sánh là -8. Có lẽ tôi sẽ sai ở một số điểm C Programming. Nhưng công việc đúng của nó;)


1
Backstroke không được thiết lập '\ b'. Nhưng nếu bạn cẩn thận gỡ lỗi thì bạn sẽ thấy '\ 0'. Vì vậy, tôi nhận được kết quả 0 là hai giá trị bằng nhau trong phương thức strcmp. const char * stoke = [văn bản cStringUsingEncoding: NSASCIIStringEncoding]; const char * backstroke = "\ 0"; // cái này bằng với \ b -> "\ x08"; strcmp (ngửa, stoke);
Yoon Lee

Ngoài ra, theo định nghĩa của strcmp (s1, s2), trả về 0 nếu s1 == s2,> 0 s1 có từ vựng lớn hơn s2 ngược lại.
Yoon Lee

Tôi không hiểu làm thế nào điều này có thể làm việc? @YoonLee: bạn cũng không strcmptrả về -1, 0, or 1à? Đó là sự hiểu biết của tôi.
chug2k

1
trong textview bạn luôn phát hiện khoảng lùi ngay cả khi không có văn bản, UITextField khác
LolaRun

2
Đây là một UITextViewDelegatephương pháp, không phải UITextFieldDelegate.
pkamb

11

Thử delegate

- (BOOL)textField:(UITextField *)textField 
        shouldChangeCharactersInRange:(NSRange)range 
        replacementString:(NSString *)string {

Sau đó kiểm tra xem cái range.length == 1nào có vẻ là trường hợp khi backspacebị đánh.


8
Chỉ được gọi khi trường không trống, mặc dù. Lưu ý câu hỏi ban đầu. :)
Eric Goldberg

Sử dụng UITextView cho việc này.
Oleg

11

vui lòng sử dụng mã bên dưới, nó sẽ giúp bạn phát hiện phím xóa bàn phím ngay cả khi trường văn bản trống.

Mục tiêu C:

- (BOOL)keyboardInputShouldDelete:(UITextField *)textField { return YES; }

Swift:

func keyboardInputShouldDelete(_ textField: UITextField) -> Bool { return true }

Tx - chỉ những gì tôi cần. Nhưng nó được ghi nhận ở đâu ??
Andy Weinstein

9

Câu trả lời của Niklas Alvaeus đã giúp tôi giải quyết vấn đề tương tự

Tôi đã giới hạn mục nhập vào một bộ ký tự cụ thể, nhưng nó đã bỏ qua các khoảng trống. Vì vậy, tôi đã kiểm tra nó range.length == 1trước khi cắt NSString. Nếu đó là sự thật, tôi chỉ trả lại chuỗi và không cắt nó. Xem bên dưới

 - (BOOL) textField:(UITextField *)textField 
          shouldChangeCharactersInRange:(NSRange)range 
          replacementString:(NSString *)string
 {
     NSCharacterSet *nonNumberSet = 
      [[NSCharacterSet characterSetWithCharactersInString:@"0123456789."] 
         invertedSet];

    if (range.length == 1) {
       return string;
    }
    else {
       return ([string stringByTrimmingCharactersInSet:nonNumberSet].length > 0);
    }   
 }

Phương thức này mong đợi một giá trị boolean và không phải là một chuỗi như giá trị trả về
Pascalius

4

Đối với những người có vấn đề về câu trả lời của Jacob, tôi đã triển khai lớp con trường văn bản của mình như sau và nó hoạt động rất tốt!

#import <UIKit/UIKit.h>

@class HTTextField;

@protocol HTBackspaceDelegate <NSObject>

@optional
- (void)textFieldDidBackspace:(HTTextField*)textField;
@end

@interface HTTextField : UITextField<UIKeyInput>

@property (nonatomic, assign) id<HTBackspaceDelegate> backspaceDelegate;

@end


#import "HTTextField.h"

@implementation HTTextField

- (void)deleteBackward {
    [super deleteBackward];
    if ([self.backspaceDelegate respondsToSelector:@selector(textFieldDidBackspace:)]){
        [self.backspaceDelegate textFieldDidBackspace:self];
    }
}

- (BOOL)keyboardInputShouldDelete:(UITextField *)textField {
    BOOL shouldDelete = YES;

    if ([UITextField instancesRespondToSelector:_cmd]) {
        BOOL (*keyboardInputShouldDelete)(id, SEL, UITextField *) = (BOOL (*)(id, SEL, UITextField *))[UITextField instanceMethodForSelector:_cmd];

        if (keyboardInputShouldDelete) {
            shouldDelete = keyboardInputShouldDelete(self, _cmd, textField);
        }
    }

    if (![textField.text length] && [[[UIDevice currentDevice] systemVersion] intValue] >= 8) {
        [self deleteBackward];
    }

    return shouldDelete;
}

@end

bạn có thể viết mã cho swift Tôi đã gặp một số lỗi "xác nhận dự phòng đối với protoco uikeyinput"
Raj Aggrawal

4

Yup, sử dụng phương pháp bên dưới để phát hiện backspace, khi textField trống.

Cần thêm UITextFieldDelegate

yourTextField.delegate = self (PHẢI BẮT BUỘC)

Nhanh:

func keyboardInputShouldDelete(_ textField: UITextField) -> Bool { 
    return true
}

Mục tiêu C:

- (BOOL)keyboardInputShouldDelete:(UITextField *)textField { 
    return YES; 
}

5
Điều này thậm chí không gọi cho tôi. Tất cả các phương thức ủy nhiệm khác đang được gọi là và khi nào cho một sự kiện xảy ra.
Hemang

Cảm ơn bạn đời .. Bạn đóng đinh nó. :)
MS.

@ McDonal_11 Tôi nghĩ bạn đã quên đặt textfield.delegate = self of textfield.
Himanshu padia

Tôi đã thiết lập. các phương thức ủy nhiệm khác của UITextField đang hoạt động tốt. Cái này một mình không làm việc. Những gì tôi nhớ ??
McDonal_11

3

Việc sử dụng tốt nhất mà tôi đã tìm thấy để phát hiện backspace là phát hiện khi người dùng đã nhấn backspace trong một khoảng trống UITextField. Ví dụ: nếu bạn có người nhận 'bong bóng' trong ứng dụng thư, khi bạn nhấn backspace trongUITextField , nó sẽ chọn người nhận 'bong bóng' cuối cùng.

Điều này có thể được thực hiện theo cách tương tự như câu trả lời của Jacob Caraballo. Nhưng trong câu trả lời của Jacob, nếu UITextFieldcó một ký tự còn lại khi bạn nhấn backspace, vào thời điểm nhận được tin nhắn đại biểu, thì UITextFieldnó sẽ trống, vì vậy bạn đang phát hiện backspacemột cách hiệu quả trên một trường văn bản có nhiều nhất một ký tự.

Trên thực tế, nếu bạn muốn phát hiện backspacetrên một UITextFieldký tự có 0 ký tự chính xác (trống), thì bạn nên gửi tin nhắn đến delegatetrước khi gọi đến super deleteBackward. Ví dụ:

#import "MyTextField.h"

//Text field that detects when backspace is hit with empty text
@implementation MyTextField

#pragma mark - UIKeyInput protocol
-(void)deleteBackward
{
  BOOL isTextFieldEmpty = (self.text.length == 0);
  if (isTextFieldEmpty) {
    if ([self.delegate 
         respondsToSelector:@selector(textFieldDidHitBackspaceWithEmptyText:)]) {

        [self.delegate textFieldDidHitBackspaceWithEmptyText:self];
        }
    }
    [super deleteBackward];
}
@end

Giao diện cho trường văn bản như vậy sẽ trông giống như thế này:

@protocol MyTextFieldDelegate;

@interface MyTextField : UITextField
@property(nonatomic, weak) id<MyTextFieldDelegate> delegate;
@end

@protocol MyTextFieldDelegate <UITextFieldDelegate>
@optional
-(void)textFieldDidHitBackspaceWithEmptyText:(MyTextField *)textField;
@end

2
Để điều này hoạt động trong iOS8 (trong đó có một lỗi khiến phương thức ủy nhiệm này không bao giờ được gọi), vui lòng xem câu trả lời sau: stackoverflow.com/a/25862878/893101 . Thêm chi tiết về lỗi ios8
pIkEL

2

Trong iOS 6, phương thức xóaBackward được gọi trên UITextField khi nhấn phím lùi, bao gồm cả khi trường trống. Vì vậy, bạn có thể phân lớp UITextField và cung cấp triển khai xóaBackward của riêng bạn (cũng gọi siêu của nó.)

Mặc dù vậy, tôi vẫn hỗ trợ iOS 5 vì vậy tôi sẽ cần kết hợp câu trả lời của Andrew và điều này.


1

:) chỉ cho tiêu đề "Phát hiện backspace", nơi tôi sử dụng UIKeyboardTypeNumberPad.

Tôi cũng gặp câu hỏi tương tự tối nay, và sau đây là mã của tôi để tìm ra nó:

- (BOOL)textField:(UITextField *)textField 
        shouldChangeCharactersInRange:(NSRange)range 
        replacementString:(NSString *)string
{
    NSLog([NSString stringWithFormat:@"%d", [string length]]);
}

Bởi vì UIKeyboardTypeNumberPad, người dùng chỉ có thể nhập Số hoặc backspace, vì vậy khi độ dài của chuỗi là 0, nó phải là phím xóa lùi.

Hy vọng ở trên sẽ làm một số trợ giúp.


Nó giống với bất kỳ loại bàn phím nào.
ma11hew28

Làm thế nào để tôi móc phương thức này lên đến trường văn bản của tôi?
dùng230910

1

Thay vì cố gắng cấu trúc lại những gì S BE ĐƯỢC trong trường văn bản hoặc tìm ra ký tự đặc biệt nào đã được nhập trong shouldChangeCharactersInRangephương thức, tôi khuyên bạn nên làm như sau:

[self performSelector:@selector(manageSearchResultsDisplay) 
           withObject:nil 
           afterDelay:0];

Điều này cho phép bạn gọi một phương thức trực tiếp sau khi hoàn thành thao tác hiện tại. Điều thú vị về điều này là, khi nó hoàn thành, giá trị được sửa đổi sẽ có trong UITextField. Tại thời điểm đó, bạn chỉ có thể kiểm tra độ dài của nó và / hoặc xác nhận dựa trên những gì có.


1

Phân lớp UITextField không hoạt động với tôi trên iOS 8.3, xóaBackward không bao giờ được gọi.

Đây là giải pháp tôi đã sử dụng, hoạt động trên tất cả các phiên bản iOS 8 và cũng sẽ hoạt động trên các phiên bản iOS khác

for textField in textFields {
            textField.text = " "
}

func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
        if string == "" && textField.text == " "   {
            // Do stuff here
            return false
        }
        return true
}

1

Trong tệp .h thêm đại biểu UIKeyInput

- (BOOL)keyboardInputShouldDelete:(UITextField *)textField {

if ([textField isEqual:_txtFirstDigit]) {

}else if([textField isEqual:_txtSecondDigit]) {
    [_txtFirstDigit becomeFirstResponder];

}else if([textField isEqual:_txtThirdDigit]) {
    [_txtSecondDigit becomeFirstResponder];

}else if([textField isEqual:_txtFourthDigit]) {
    [_txtThirdDigit becomeFirstResponder];
}
return YES;
}   

định dạng được cải thiện


1

Tôi đã triển khai giải pháp tương tự với các cải tiến nhỏ sẽ cho tôi biết rằng nếu trường văn bản có bất kỳ giá trị nào trong khi người dùng đã gõ phím lùi. Điều này hữu ích cho trường hợp của tôi khi tôi chỉ nên tập trung vào một trường văn bản khác nếu trường văn bản trống khi nhấn phím lùi.

protocol MyTextFieldDelegate : UITextFieldDelegate {
    func textFieldDidDelete(textField: MyTextField, hasValue: Bool)
}

override func deleteBackward() {
    let currentText = self.text ?? ""
    super.deleteBackward()
    let hasValue = currentText.isEmpty ? false : true
    if let delegate = self.delegate as? MyTextFieldDelegate {
        delegate.textFieldDidDelete(textField: self, hasValue: hasValue)
    }
}

1

Câu trả lời nhiều nhất là thiếu một điều - khả năng phát hiện xem trường văn bản có trống hay không.

Đó là, khi bạn ghi đè phương thức xóaBackwards () của lớp con TextField, bạn vẫn không biết liệu trường văn bản đã trống chưa. (Cả trước và sau khi xóaBackwards (), textField.text!là một chuỗi trống:"" :)

Đây là sự cải thiện của tôi, với một kiểm tra cho sự trống rỗng trước khi xóa.

1. Tạo giao thức đại biểu mở rộng UITextFieldDelegate

protocol MyTextFieldDelegate: UITextFieldDelegate {
    func textField(_ textField: UITextField, didDeleteBackwardAnd wasEmpty: Bool)
}

2. Phân lớp UITextField

class MyTextField: UITextField {
    override func deleteBackward() {
        // see if text was empty
        let wasEmpty = text == nil || text! == ""

        // then perform normal behavior
        super.deleteBackward()

        // now, notify delegate (if existent)
        (delegate as? MyTextFieldDelegate)?.textField(self, didDeleteBackwardAnd: wasEmpty)
    }
}

3. Thực hiện giao thức đại biểu mới của bạn

extension MyViewController: MyTextFieldDelegate {
    func textField(_ textField: UITextField, didDeleteBackwardAnd wasEmpty: Bool) {
        if wasEmpty {
            // do what you want here...
        }
    }
}

1

Trình xử lý toàn diện cho trường văn bản với số có một chữ số cho Swift 5.1 :

  • Giả sử rằng bạn có bộ sưu tập textFields (cũng có các đại biểu được kết nối)

1 bước

protocol MyTextFieldDelegate: class {
    func textField(_ textField: UITextField, didDeleteBackwardAnd wasEmpty: Bool) 
}

final class MyTextField: UITextField {

    weak var myDelegate: MyTextFieldDelegate?

    override func deleteBackward() {
        let wasEmpty = text == nil || text == ""

        // then perform normal behavior
        super.deleteBackward()

        // now, notify delegate (if existent)
        (delegate as? MyTextFieldDelegate)?.textField(self, didDeleteBackwardAnd: wasEmpty)
    }
}

2 bước

final class ViewController: UIViewController {

    @IBOutlet private var textFields: [MyTextField]!

    override func viewDidLoad() {
        super.viewDidLoad()
        textFields.forEach {
            $0.delegate = self
            $0.myDelegate = self
        }
    }
}

3 bước

extension ViewController: UITextFieldDelegate, MyTextFieldDelegate {
    func textFieldHasChanged(with text: String, _ tag: Int, for textField: UITextField) {
        textField.text = text

        if let someTextField = (textFields.filter { $0.tag == tag }).first {
            someTextField.becomeFirstResponder()
        } else {
            view.endEditing(true)
        }
    }

    func textField(_ textField: UITextField, didDeleteBackwardAnd wasEmpty: Bool) {
        // If the user was pressing backward and the value was empty, go to previous textField
        textFieldHasChanged(with: "", textField.tag - 1, for: textField)
    }

    func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
        // Restrict to only digits
        let aSet = NSCharacterSet(charactersIn: "0123456789").inverted
        let compSepByCharInSet = string.components(separatedBy: aSet)
        let numberFiltered = compSepByCharInSet.joined(separator: "")

        guard string == numberFiltered, let text = textField.text else { return false }

        if text.count >= 1 && string.isEmpty {
            // If the user is deleting the value
            textFieldHasChanged(with: "", textField.tag - 1, for: textField)
        } else {
            textFieldHasChanged(with: string, textField.tag + 1, for: textField)
        }

        return false
    }
}

0

Đây là giải pháp của tôi dựa trên ý tưởng @andrew:

ở đâu đó, ví dụ như trong viewDidLoad

        textField.delegate = self
        textField.addTarget(self, action: #selector(valueChanged(_:)), for: .editingDidBegin)

và sau đó

    @objc func valueChanged(_ textField: UITextField) {
        textField.text = "\u{200B}"
    }

    override func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
        textField.text = string
        if string == "" {
            //backpaspace pressed 
        }

0

Bạn có thể kiểm tra văn bản của chế độ xem / trường văn bản để xem nó có trống không và đảm bảo văn bản thay thế cũng trống trong phương thức ủy nhiệm nênChangeTextIn.

func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
    if (textView.text == "" && text == "") {
        print("Backspace on empty text field.")
    }
    return true
}

-2

Một cái gì đó như thế này:

- (BOOL)textField:(UITextField *)textField 
        shouldChangeCharactersInRange:(NSRange)range 
        replacementString:(NSString *)string       
{  
    if (![text hash] && ![textField.text length])  
        [self backspaceInEmptyTextField];  
}

tất nhiên hàm băm dành cho một chuỗi ký tự.


-2

Sử dụng phương thức TextField Delegate:

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string

Thêm mã sau đây trong phương pháp trên để phát hiện sự kiện xóa

if(textField == YourTextField)
{
    if ([string length] == 0 && range.length > 0)
    {
        // Your Code after deletion of character
    }
}

-3

Để giữ cho nó đơn giản ở đây là điều kiện duy nhất bạn cần kiểm tra

     if (range.length==1)

-3
+ (BOOL)detectBackspaceOnly:(NSString *)string
{
    for(int i=0 ; i<string.length ; i++){
        unichar caract = [string characterAtIndex:i];
        if(caract != ' ' && caract != '\n')
            return NO;
    }

    return YES;
}

2
Có lẽ một lời giải thích nhỏ để đặt này?
Alex Cio

-4

Trong UITextViewDelegate:

- (BOOL)               textView:(UITextView *)textView 
        shouldChangeTextInRange:(NSRange)range 
                replacementText:(NSString *)text
{
    if(text isEqualToString:@"");
    {
        NSLog(@"press backspace.");
    }
}

nó hoạt động tốt cho tôi

cập nhật cho đầu vào chữ viết tắt tiếng Trung Quốc và chữ viết tay tiếng Trung:

- (BOOL)               textView:(UITextView *)textView 
        shouldChangeTextInRange:(NSRange)range 
                replacementText:(NSString *)text
{
    if (range.length > 0 && [text isEqualToString:@""]) {
        NSLog(@"press Backspace.");
    }
    return YES;
}

căn cứ vào tài liệu nói:

"Nếu người dùng nhấn phím deleteKey, độ dài của phạm vi là 1 và một đối tượng chuỗi trống sẽ thay thế ký tự đơn đó."


1
Câu hỏi này là về UITextField, không phải UITextView.
ma11hew28
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.