การใช้ `textField: shouldChangeCharactersInRange:` ฉันจะรับข้อความรวมถึงอักขระที่พิมพ์ในปัจจุบันได้อย่างไร


116

ฉันใช้รหัสด้านล่างเพื่อลองและtextField2อัปเดตเนื้อหาข้อความให้ตรงกับtextField1ทุกครั้งที่ผู้ใช้พิมพ์เข้าtextField1มา

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

อย่างไรก็ตามผลลัพธ์ที่ฉันสังเกตได้คือ ...

textField2 คือ "12" เมื่อ textField1 เป็น "123"

textField2 คือ "123" เมื่อ textField1 เป็น "1234"

... เมื่อสิ่งที่ฉันต้องการคือ:

textField2 คือ "123" เมื่อ textField1 เป็น "123"

textField2 คือ "1234" เมื่อ textField1 เป็น "1234"

ผมทำอะไรผิดหรือเปล่า?


8
ขอย้ำอีกครั้งว่าการใช้เหตุการณ์"แก้ไขเปลี่ยนแปลง"นั้นง่ายกว่ามาก.. เพียงลากใน IB ไปยังฟังก์ชันที่คุณสร้าง
Fattie

โปรดทราบว่าเหตุการณ์ที่เปลี่ยนแปลงการแก้ไขจะไม่จับเหตุการณ์การเปลี่ยนแปลงข้อความใด ๆ ที่สร้างขึ้นโดยใช้โปรแกรมเช่นการแก้ไขอัตโนมัติ / การเติมข้อความอัตโนมัติ / การแทนที่ข้อความ
ชิม

คำตอบ:


272

-shouldChangeCharactersInRangeถูกเรียกก่อนฟิลด์ข้อความจะเปลี่ยนข้อความจริง ๆ นั่นคือเหตุผลที่คุณได้รับค่าข้อความเก่า ในการรับข้อความหลังการอัปเดตให้ใช้:

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

15
นี้เกือบจะทำงานให้ฉัน ถ้าฉันพิมพ์อักขระสิ่งนี้ได้ผล ถ้าฉันกดปุ่มลบมันจะลบสองตัวอักษร สำหรับฉันคำแนะนำต่อไปนี้ใช้ได้ผล: stackoverflow.com/questions/388237/… โดยพื้นฐานแล้วให้ลาก'n'drop จาก UITextField ลงในโค้ดของคุณ (เพื่อสร้างฟังก์ชัน) จากนั้นคลิกขวาที่ TextField ของคุณแล้วลาก'n ' จากวงกลมสำหรับ "การแก้ไขเปลี่ยนแปลง" ไปยังฟังก์ชันใหม่ของคุณ (เฮ้อคิดถึง Visual Studio บ้าง .. )
Mike Gledhill

ฉันรู้สึกว่านี่เป็นคำตอบที่ถูกต้อง แต่ไม่ใช่คำตอบ วิธีที่ดีที่สุดในการบรรลุสิ่งที่คุณต้องการได้รับคำตอบโดย @tomute
Pedro Borges

5
หรือ textFiel.text = (textFiel.text เป็น NSString) .stringByReplacingCharactersInRange (range, withString: string) ใน Swift
สูงสุด

@MikeGledhill คุณสามารถทำสิ่งเดียวกันโดยใช้โปรแกรม:[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

สวิฟต์ 3

จากคำตอบที่ยอมรับสิ่งต่อไปนี้ควรใช้งานได้ใน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
}

บันทึก

ทั้งสองStringและวิธีการได้เรียกว่าNSString replacingCharacters:inRange:withStringแต่คาดว่าจะเป็นอดีตคาดว่าตัวอย่างของในขณะที่คาดว่าหลังเป็นตัวอย่างของRange วิธีผู้รับมอบสิทธิ์ใช้อินสแตนซ์จึงใช้ในกรณีนี้NSRangetextFieldNSRangeNSString


replacingCharactersควรจะเป็นstringByReplacingCharactersInRange
Alan Scarpa

1
@Alan_s ฉันคัดลอกข้อมูลโค้ดนี้โดยตรงจากโปรเจ็กต์ Xcode ของฉันและมันก็ใช้งานได้ดี คุณใช้ Xcode 8.1 โดยกำหนดเป้าหมายเป็น iOS 10.1 หรือไม่
focorner


13

ใน Swift (4) โดยไม่มีNSString(Pure Swift):

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
}

เป็นส่วนขยาย:

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

เวอร์ชัน Swift สำหรับมัน:

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

นี่คือรหัสที่คุณต้องการ

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

1

ใช้ยาม

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

UITextFieldTextDidChangeNotificationวิธีการแก้ปัญหาของฉันคือการใช้งาน

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

อย่าลืมโทร[[NSNotificationCenter defaultCenter] removeObserver:self];เข้าdeallocเมธอด


โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.