Menggunakan `textField: shouldChangeCharactersInRange:`, bagaimana cara mendapatkan teks termasuk karakter yang saat ini diketik?


116

Saya menggunakan kode di bawah ini untuk mencoba dan meminta textField2agar konten teks diperbarui agar cocok textField1setiap kali pengguna mengetik textField1.

- (BOOL) textField: (UITextField *)theTextField shouldChangeCharactersInRange: (NSRange)range replacementString: (NSString *)string {    
  if (theTextField == textField1){    
     [textField2 setText:[textField1 text]];    
  }
}

Namun, output yang saya amati adalah ...

textField2 adalah "12", jika textField1 adalah "123"

textField2 adalah "123", jika textField1 adalah "1234"

... ketika yang saya inginkan adalah:

textField2 adalah "123", jika textField1 adalah "123"

textField2 adalah "1234", jika textField1 adalah "1234"

Apa yang saya lakukan salah?


8
Sebagai pengingat, sangatlah mudah untuk selalu menggunakan acara "Mengedit Berubah" .. cukup seret ke IB ke fungsi yang Anda buat.
Fattie

Perhatikan bahwa pengeditan peristiwa yang diubah tidak menangkap teks apa pun yang mengubah peristiwa yang dihasilkan secara terprogram, misalnya koreksi otomatis / pelengkapan otomatis / penggantian teks.
shim

Jawaban:


272

-shouldChangeCharactersInRangedipanggil sebelum bidang teks benar-benar mengubah teksnya, itulah mengapa Anda mendapatkan nilai teks lama. Untuk mendapatkan teks setelah penggunaan pembaruan:

[textField2 setText:[textField1.text stringByReplacingCharactersInRange:range withString:string]];

15
Ini hampir berhasil bagi saya. Jika saya mengetik karakter, ini berhasil. Jika saya menekan tombol hapus, itu akan menghapus dua karakter. Bagi saya, saran berikut berhasil: stackoverflow.com/questions/388237/… Pada dasarnya, seret'n'drop dari UITextField ke dalam kode Anda (untuk membuat fungsi), lalu klik kanan pada TextField Anda, dan seret'n ' jatuhkan dari lingkaran untuk "Pengeditan Berubah" ke fungsi baru Anda. (Sigh. Kadang-kadang saya merindukan Visual Studio ..)
Mike Gledhill

Saya juga merasa ini adalah jawaban yang valid, tetapi bukan jawaban ATAS. Cara terbaik untuk mencapai apa yang Anda inginkan dijawab oleh @tomute
Pedro Borges

5
Atau textFiel.text = (textFiel.text as NSString) .stringByReplacingCharactersInRange (range, withString: string) di Swift
Max

@MikeGledhill Anda dapat melakukan hal yang sama secara terprogram:[textField addTarget:self action:@selector(textFieldEditingChanged:) forControlEvents:UIControlEventEditingChanged]
Steve Moser

52
-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
    NSString * searchStr = [textField.text stringByReplacingCharactersInRange:range withString:string];

    NSLog(@"%@",searchStr);
    return YES;
}

40

Cepat 3

Berdasarkan jawaban yang diterima, berikut ini seharusnya berfungsi di Swift 3 :

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {

    let newString = NSString(string: textField.text!).replacingCharacters(in: range, with: string)

    return true
}

Catatan

Keduanya Stringdan NSStringmemiliki metode yang dipanggil replacingCharacters:inRange:withString. Namun, seperti yang diharapkan, yang pertama mengharapkan instance dari Range, sedangkan yang terakhir mengharapkan instance NSRange. The textFieldmetode delegasi menggunakan NSRangecontoh, sehingga penggunaan NSStringdalam kasus ini.


replacingCharactersseharusnyastringByReplacingCharactersInRange
Alan Scarpa

1
@Alan_s Saya menyalin potongan ini langsung dari proyek Xcode saya dan itu berfungsi dengan baik. Apakah Anda menggunakan Xcode 8.1 dengan target ke iOS 10.1?
focorner


13

Di Swift (4), tanpa NSString(Swift murni):

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {

    if let textFieldString = textField.text, let swtRange = Range(range, in: textFieldString) {

        let fullString = textFieldString.replacingCharacters(in: swtRange, with: string)

        print("FullString: \(fullString)")
    }

    return true
}

Sebagai perpanjangan:

extension UITextField {

    func fullTextWith(range: NSRange, replacementString: String) -> String? {

        if let fullSearchString = self.text, let swtRange = Range(range, in: fullSearchString) {

            return fullSearchString.replacingCharacters(in: swtRange, with: replacementString)
        }

        return nil
    }
}

// Usage:

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {

    if let textFieldString = textField.fullTextWith(range: range, replacementString: string) {
        print("FullString: \(textFieldString)")
    }

    return true
}

8

Versi Swift untuk itu:

func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {

    if string == " " {
        return false
    }

    let userEnteredString = textField.text

    var newString = (userEnteredString! as NSString).stringByReplacingCharactersInRange(range, withString: string) as NSString

    print(newString)

    return true
}

5

Ini adalah kode yang Anda butuhkan,

if ([textField isEqual:self.textField1])
  textField2.text = [textField1.text stringByReplacingCharactersInRange:range withString:string];

1

gunakan penjaga

func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
        guard case let textFieldString as NSString = textField.text where
            textFieldString.stringByReplacingCharactersInRange(range, withString: string).length <= maxLength else {
                return false
        }
        return true
    }

0

Solusi saya adalah menggunakan UITextFieldTextDidChangeNotification.

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(copyText:) name:UITextFieldTextDidChangeNotification object:nil];

Jangan lupa menelepon [[NSNotificationCenter defaultCenter] removeObserver:self];di deallocmethod.


Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.