Boş UITextField'da geri tuşu algıla


126

Boş bir klavyede iPhone klavyesinde Backspace/ Deletetuşuna basıldığında bunu algılamanın bir yolu var mı UITextField? BackspaceSadece UITextFieldboş ise ne zaman basıldığını bilmek istiyorum .


Bir yorumda @Alex Reynolds'un önerisine dayanarak, metin alanımı oluştururken aşağıdaki kodu ekledim:

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

Bu bildirim alındı ​​( handleTextFieldChangedişlev çağrıldı), ancak Backspaceboş bir alanda tuşa bastığımda hala gelmiyor . Herhangi bir fikir?


Bu sorunun etrafında bazı karışıklıklar var gibi görünüyor. BackspaceTuşa basıldığında bir bildirim almak istiyorum . Bu kadar. Ancak çözüm UITextFieldzaten boş olduğunda da işe yaramalıdır.


Sanırım "yalnızca klavye boşsa" yerine "yalnızca UITextField boşsa" demek istersiniz ...?
Steve Harrison

@Steve Harrison: teşekkürler. Bunu güncelledi.
marcc

Benzer bir şey yapmaya çalışıyorum, o zaman hangi çözümü buldunuz? Yaptığım şey, kaydırma görünümünde bir metin alanı, bir metin yazdığımda, öneriler gösteriliyor ve birine tıkladığımda metin alanının soluna bir etiket nesnesi yerleştiriliyor. Şimdiden teşekkürler: D
Dough

Çalışma zamanı hilesi
Jano

4
Bu kadar önemsiz bir şeyi gülünç derecede özlüyorum. Bu zor olmamalı.
Adam Waite

Yanıtlar:


36

Bu uzun bir atış olabilir ama işe yarayabilir. Metin alanının metnini sıfır genişlikli boşluk karakterine ayarlamayı deneyin \u200B. Boş görünen bir metin alanına geri tuşuna basıldığında, aslında alanınızı siler. Ardından alanı yeniden yerleştirebilirsiniz.

Kullanıcı imleci alanın soluna taşımayı başarırsa çalışmayabilir.


3
@Andrew, uygulamaya karar verdiğim yaklaşım bu. Biraz kod gerektirdi ama kesinlikle etkili. Bana yanlış bir şey yaptığımı söylemeye çalışmak yerine yardımın için teşekkürler.
marcc

2
Bu teknik iPhone> 3.1.3'te işe yarayabilir, ancak hantaldır ve gelecekteki sürümlerde bozulabilir, vb. Sanırım iPhone / iOS'ta klavye silme tuşunu nasıl algılayacağıma dair daha temiz ve daha kararlı bir çözüm buldum .
ma11hew28

6
Kullanıcı imleci boşluğun soluna getirmeyi başarırsa silme işleminin algılanmadığını onaylayabilirim. Bunu düzeltmek için nasıl anlamaya, o zaman da alt sınıf gerekir UITextFieldve uygulamak canPerformAction:withSender:için return NOiçin select:ve selectAll:metin dizesine eşit olduğunda eylemler @"\u200B".
ma11hew28

2
Sorun, bunun güvenli test alanları için çalışmamasıdır. Bununla nasıl başa çıkacağına dair bir fikrin var mı?
Kyle Clegg

7
Üzgünüm ama bu fikir kötü. İnanılmaz hilekar ve 30 kadar olumlu oyla kabul edilen yanıt olmamalı. Diğer yorumcuların bahsettiği gibi, bunun yerine UITextField'ı alt sınıflara ayırırdım.
Brian Sachetta

155

Swift 4:


Alt sınıf UITextField:

// MyTextField.swift
import UIKit

protocol MyTextFieldDelegate: AnyObject {
    func textFieldDidDelete()
}

class MyTextField: UITextField {

    weak var myDelegate: MyTextFieldDelegate?

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

}

Uygulama:

// 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")
    }

}

Objective-C:


Alt sınıf 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

Şimdi MyTextFieldDelegate'iUIViewController sizin UITextFields hesabınıza ekleyin ve myDelegate'inizi şu şekilde ayarlayın 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
En iyi çözüm budur. Kabul edilen cevap bir kesmedir. Hedef C, alt sınıflamaya dayalıdır ve bu çözüm, sorunu çözmek için onu doğru şekilde kullanır.
TJ

ViewController Metin alanımın temsilcisiniUITextFieldUIViewController
rohan-patel

4
Görünüşe göre bu, Apple Bug gibi görünen şey nedeniyle şu anda ios8'de çalışmıyor: devforums.apple.com/message/1045312#1045312
chug2k

1
Cevabımda olduğu gibi ios8 hatası için geçici bir çözüm kullandım ve işe yaradı. Çözüm arayanlar için faydalı olabilir.
furkan3ayraktar

1
deleteBackward()eğer denilen olmayacak return falseiçindetextField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool
igrrik

41

Güncelleme: Geçersiz kılan bir örnek için JacobCaraballo'nun cevabına bakın -[UITextField deleteBackward].

Check out UITextInput, özellikle silme tuşuna basıldığında her zaman çağrılan UIKeyInputbir deleteBackwardtemsilci yöntemine sahiptir . Basit bir şey yapıyorsanız, SimpleTextInput ve bu iPhone UIKeyInput Örneği tarafından yapıldığı gibi, yalnızca alt sınıflamayı ve protokole uydurmayı düşünebilirsiniz . Not: ve akrabaları (dahil ) yalnızca iOS 3.2 ve sonraki sürümlerde mevcuttur.UILabelUIKeyInputUITextInputUIKeyInput


2
Bu doğru cevap. UITextField'ın hızlı bir alt sınıfıyla, bilgisayar korsanlığı yok ve çok basit.
Sam

Yakup'un cevabını aşağıda buldum. Bunun ayrıntılı bir örneğini veriyor.
Sam

Bu cevabın iOS 5'te çalışmadığını belirtmek gerekir. Metin alanı boşsa geri tuşuna basmak bu yöntemi başlatmaz.
jfeldman

31

Aşağıdaki gibi kod:

@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

Sonunda, Metin Alanının Özel Sınıf özelliğini "MyTextField" olarak değiştirmeyi unutmayın.


5
Kabul edilen cevap bu olmalıdır. Temiz ve aslında soruyu cevaplıyor.
Ryan Romanchuk

1
Soruyu cevaplıyor ... iOS 6.0+ hedeflediğiniz sürece. İOS 5'te, deleteBackward maalesef asla alt sınıfınızda çağrılmadı.
BJ Homer

2
BJ Homer, cihazların% 93'ü iOS 6'da, bu nedenle iOS 5'i hedeflememek genellikle çok da önemli değil.
Jonathan.

2
Bunu bulacak kadar aşağı kaydırdığıma sevindim. Bunu bugün IOS 7'de yapmanın% 100 doğru yolu.
MusiGenesis

Bu soru için sadece geçici çözümler olan pek çok başka cevap gördüm ve bunların hiçbiri geri al tuşuna boş bir alanda basıldığı durumla neredeyse hiç ilgilenmiyor. Ancak bu mükemmel ve bunu yapmanın gerçekten temiz bir yolu.
Christopher Hannah

19

Hızlı uygulama:

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)
        }
    }
}

Teşekkürler, bu yöntemin Apple tarafından önerildiğini veya hacklendiğini biliyor olabilir miyim? metin alanı için belgelenmemiş görünüyor.
kalpesh jetani

Bir textView ile benim için çalıştı. paylaştığınız için teşekkürler;)
Edouard Barbier

Metin alanı boş olduğunda ve geri alan tıklandığında benim için çalıştı.
Ramakrishna

17

Çözümden daha kolay başka bir yol buldum subclass. Hatta biraz garip ama iyi çalışıyor.

- (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;
}

Karşılaştırma sonucunun -8 olması biraz garip. Belki bir noktada yanılıyorum C Programming. Ama doğru çalışması;)


1
Sırtüstü '\ b' ayarlanmadı. Ancak dikkatli bir şekilde hata ayıklama yaparsanız, '\ 0' göreceksiniz. Böylece strcmp yönteminde iki değer eşit olan 0 sonucunu alıyorum. const char * stoke = [text cStringUsingEncoding: NSASCIIStringEncoding]; const char * backstroke = "\ 0"; // bu eşittir \ b -> "\ x08"; strcmp (sırtüstü, durma);
Yoon Lee

Ayrıca, strcmp (s1, s2) tanımına göre, eğer s1 == s2 ise 0 döndürür,> 0 s1 sözlükbilimsel olarak s2'den büyükse bunun tersi de geçerlidir.
Yoon Lee

Bunun nasıl işe yarayacağını anlamıyorum? @YoonLee: Geri strcmpdönüşler de demiyor -1, 0, or 1musun? Benim anlayışım buydu.
chug2k

1
metin görünümünde metin olmasa bile her zaman geri
boşluğu algılarsınız

2
Bu bir UITextViewDelegateyöntem, değil UITextFieldDelegate.
pkamb

12

Deneyin delegate

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

Sonra kontrol edin range.length == 1backspace , vurulduğunda durumun böyle .


8
Yine de yalnızca alan boş olmadığında çağrılır. Orijinal soruyu not edin. :)
Eric Goldberg

Bunun için UITextView kullanın.
Oleg

11

Lütfen aşağıdaki kodu kullanın, metin alanı boş olsa bile klavye silme tuşunu tespit etmenize yardımcı olacaktır.

Hedef C:

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

Swift:

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

Tx - tam da ihtiyacım olan şey. Ama nerede belgeleniyor?
Andy Weinstein

9

Niklas Alvaeus'un cevabı benzer bir sorunla bana yardımcı oldu

Girişi belirli bir karakter setiyle sınırlıyordum, ancak geri boşlukları göz ardı ediyordu. Bu yüzden range.length == 1kırpmadan önce kontrol ettirdim NSString. Doğruysa, dizeyi döndürürüm ve kırpmam. Aşağıya bakınız

 - (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);
    }   
 }

Yöntem, dönüş değeri olarak bir dize değil, bir mantıksal değer bekliyor
Pascalius

4

Jacob'ın cevabıyla ilgili sorunları olanlar için metin alanı alt sınıfımı aşağıdaki gibi uyguladım ve harika çalışıyor!

#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

swift kodunu yazabilir misin? "Uikeyinput protokolüne gereksiz doğrulama" hatası aldım
Raj Aggrawal

4

Yup, textField boş olduğunda geri tuşu algılamak için aşağıdaki yöntemi kullanın.

UITextFieldDelegate eklemeniz gerekiyor

yourTextField.delegate = self ( GEREKLİDİR )

Swift:

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

Hedef C:

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

5
Bu beni çağırmıyor bile. Diğer tüm temsilci yöntemleri, bir olay için ve ne zaman meydana geldiğinde çağrılır.
Hemang

Teşekkürler dostum .. Başardın. :)
MS.

@ McDonal_11 textfield.delegate = self of textfield ayarlamayı unuttuğunuzu düşünüyorum.
Himanshu padia

Ben ayarladım. diğer UITextField'ın temsilci yöntemleri iyi çalışıyor. Bu tek başına çalışmıyor. Ne kaçırdım ??
McDonal_11

3

Geri tuşu algılamak için bulduğum en iyi kullanım, kullanıcının boş bir boşlukta geri tuşuna bastığını algılamaktır UITextField. Örneğin, posta uygulamasında alıcılar 'köpürtülmüş' ise,UITextField , , son 'kabarcıklı' alıcıyı seçer.

Bu, Jacob Caraballo'nun cevabına benzer şekilde yapılabilir. Ancak Jacob'ın cevabında, UITextFieldgeri tuşuna bastığınızda bir karakter kaldıysa, delege mesajı alındığında UITextFieldzaten boş olacaktır, bu yüzden etkili bir şekilde tespit edersiniz.backspace en fazla bir karakter içeren bir metin alanında bir .

Aslında, tam olarak sıfır karakterli (boş) backspacebir a üzerinde algılamak istiyorsanız UITextField, o zaman mesajı delegatearamadan önce göndermelisiniz super deleteBackward. Örneğin:

#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

Böyle bir metin alanı için arayüz şuna benzer:

@protocol MyTextFieldDelegate;

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

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

2
Bunun iOS8'de çalışması için (bu temsilci yönteminin asla çağrılmamasına neden olan bir hatanın olduğu durumlarda), lütfen şu yanıta bakın: stackoverflow.com/a/25862878/893101 . İos8 hatasıyla ilgili daha fazla ayrıntı: devforums.apple.com/message/1009150#1009150
pIkEL

2

İOS 6'da, alanın boş olduğu durumlar da dahil olmak üzere geri al tuşuna basıldığında UITextField'da deleteBackward yöntemi çağrılır. Böylece, UITextField'ı alt sınıflara ayırabilir ve kendi deleteBackward uygulamanızı sağlayabilirsiniz (süperleri de çağırabilirsiniz.)

Yine de iOS 5'i destekliyorum, bu yüzden Andrew'un cevabıyla bunun bir kombinasyonuna ihtiyacım olacak.


1

:) sadece kullandığım "Geri tuşu algıla" başlığı için UIKeyboardTypeNumberPad .

Ben de bu gece aynı soruyla karşılaşıyorum ve bunu bulmak için kodum şu:

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

Çünkü UIKeyboardTypeNumberPad , kullanıcı yalnızca Number veya backspace girebilir, bu nedenle string uzunluğu 0 olduğunda, backspace anahtarı olmalıdır.

Umarım yukarıdakiler biraz yardımcı olur.


Tüm klavye türleriyle aynıdır.
ma11hew28

bu yöntemi metin alanıma nasıl bağlarım?
user230910

1

Metin alanında NELER OLACAĞINI önceden oluşturmaya çalışmak veya shouldChangeCharactersInRangeyönteme hangi özel karakterin girildiğini anlamaya çalışmak yerine , aşağıdakileri yapmayı öneririm:

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

Bu, geçerli işlem tamamlandıktan hemen sonra bir yöntemi çağırmanıza olanak tanır. Bununla ilgili harika olan şey, tamamlandığında, değiştirilen değerin zaten UITextField. Bu noktada, uzunluğunu kontrol edebilir ve / veya oradakilere göre doğrulayabilirsiniz.


1

UITextField alt sınıflandırma benim için iOS 8.3'te işe yaramadı, deleteBackward hiçbir zaman çağrılmadı.

İşte kullandığım çözüm, tüm iOS 8 sürümlerinde çalışıyor ve diğer iOS sürümlerinde de çalışmalı

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

.H dosyasında UIKeyInput temsilcisini ekleyin

- (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;
}   

geliştirilmiş Biçimlendirme


1

Benzer çözümü, kullanıcı geri alanına dokunduğunda metin alanının herhangi bir değeri olup olmadığını söyleyecek küçük iyileştirmelerle uyguladım. Bu, geri al tuşuna basıldığında metin alanı boşsa yalnızca başka bir metin alanına odaklanmam gerektiğinde kullanışlıdır.

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

En popüler cevap bir şeyi kaçırmaktır - metin alanının boş olup olmadığını tespit etme yeteneği.

Yani, bir TextField alt sınıfının deleteBackwards () yöntemini geçersiz kıldığınızda, metin alanının zaten boş olup olmadığını hala bilmiyorsunuz. (DeleteBackwards () öncesi ve sonrası textField.text!boş bir dizedir:"" )

İşte silme işleminden önce boşluğu kontrol ederek iyileştirmem.

1. UITextFieldDelegate'i genişleten bir temsilci protokolü oluşturun

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

2. Alt sınıf 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. Yeni temsilci prosedürünü uygulamaya geçirin

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

1

Swift 5.1 için tek haneli sayıya sahip metin alanı için kapsamlı işleyici :

  • TextFields çıkış koleksiyonunuz olduğunu varsayarsak (bağlı delegelerle de)

1 Adım

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 Adım

final class ViewController: UIViewController {

    @IBOutlet private var textFields: [MyTextField]!

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

3 Adım

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

İşte @andrew fikrine dayanan çözümüm:

bir yerde, örneğin viewDidLoad'da

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

ve sonra

    @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

Boş olup olmadığını görmek için metin görünümünün / alanının metnini kontrol edebilir ve shouldChangeTextIn delegate yönteminde değiştirme metninin de boş olduğundan emin olabilirsiniz.

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

-2

Bunun gibi bir şey:

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

elbette hash bir karakter dizisi içindir.


-2

TextField Delegate yöntemini kullanarak:

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

Silme olayını algılamak için yukarıdaki yönteme aşağıdaki kodu ekleyin

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

-3

Basit tutmak için kontrol etmeniz gereken tek koşul burada

     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
Belki bunu nereye koyacağına dair küçük bir açıklama?
Alex Cio

-4

İçinde UITextViewDelegate:

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

benim için iyi çalışıyor.

Basitleştirilmiş Çince pinyin ve Çince el yazısı girişi için güncelleme:

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

belgenin temelinde şöyle diyor:

"Kullanıcı tuşuna basarsa, deleteKeyaralığın uzunluğu 1 olur ve boş bir dize nesnesi bu tek karakterin yerini alır."


1
Bu soru UITextFieldbununla ilgili değil UITextView.
ma11hew28
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.