เหตุการณ์การเปลี่ยนแปลงข้อความ UITextField


563

ฉันจะตรวจจับการเปลี่ยนแปลงข้อความใด ๆ ในฟิลด์ข้อความได้อย่างไร วิธีการมอบหมายให้shouldChangeCharactersInRangeทำงานได้บางอย่าง แต่ก็ไม่ได้ตอบสนองความต้องการของฉันอย่างแน่นอน เนื่องจากจนกว่าจะส่งคืนใช่ข้อความ textField จะไม่สามารถใช้ได้กับวิธีการสังเกตการณ์อื่น ๆ

เช่นในรหัสของฉันcalculateAndUpdateTextFieldsไม่ได้รับข้อความที่ปรับปรุงผู้ใช้พิมพ์

เป็นวิธีการของพวกเขาเพื่อรับสิ่งใดเช่นtextChangedJava event handler

- (BOOL)textField:(UITextField *)textField 
            shouldChangeCharactersInRange:(NSRange)range 
            replacementString:(NSString *)string 
{
    if (textField.tag == kTextFieldTagSubtotal 
        || textField.tag == kTextFieldTagSubtotalDecimal
        || textField.tag == kTextFieldTagShipping
        || textField.tag == kTextFieldTagShippingDecimal) 
    {
        [self calculateAndUpdateTextFields];

    }

    return YES;
}

3
นี่คือตัวอย่างที่ดีของคำตอบ SO 1000 คะแนนโหวตที่ไม่ถูกต้องสมบูรณ์ iOS นั้นยากลำบาก suibtle และเต็มไปด้วย gotchyas
Fattie

คำตอบ:


1056

จากวิธีที่เหมาะสมในการเปลี่ยนข้อความ uitextfield โทรกลับ :

ฉันจับตัวละครที่ส่งไปยังตัวควบคุม UITextField เช่นนี้:

// Add a "textFieldDidChange" notification method to the text field control.

ในวัตถุประสงค์ -C:

[textField addTarget:self 
              action:@selector(textFieldDidChange:) 
    forControlEvents:UIControlEventEditingChanged];

ในสวิฟต์:

textField.addTarget(self, action: #selector(textFieldDidChange), for: .editingChanged)

จากนั้นในtextFieldDidChangeวิธีการที่คุณสามารถตรวจสอบเนื้อหาของ textField และโหลดมุมมองตารางของคุณใหม่ได้ตามต้องการ

คุณสามารถใช้ที่และใส่calculateAndUpdateTextFieldsselectorเป็นของคุณ


18
นี่เป็นทางออกที่ดีกว่า - เพราะคุณสามารถตั้งค่านี้ในไส้ปากกาหรือกระดานเรื่องราวและคุณไม่จำเป็นต้องเขียน UITextFieldTextDidChangeNotification Code มากเกินไป
PostCodeism

3
ปัญหาเดียวคือ มันไม่ทำงานสำหรับฉันพร้อมกับ - (BOOL) textField: (UITextField *) textField ควรChangeCharactersInRange: (NSRange) ช่วง replaceString: (NSString *) สตริง
iWheelBuy

4
@iWheelBuy เฉพาะเมื่อมีการส่งคืนNOซึ่งเป็นเหตุผลเพราะเมื่อคุณกลับมาNOจากวิธีนี้คุณจะบอกว่าข้อความในฟิลด์ไม่ควรเปลี่ยนแปลง
gitaarik

2
นี่คือที่ดีสำหรับการแก้ไขที่เกิดจากการเปลี่ยนแปลง textField.text = "Some new value";มันไม่ได้จับการเปลี่ยนแปลงการเขียนโปรแกรมที่เกิดขึ้นผ่าน: มีวิธีที่ฉลาดในการจับสิ่งนี้หรือไม่?
Benjohn

10
คุณจะคิดกับ Apple UITextFieldDelegateว่ามีบางอย่างที่เหมือนfunc textField: UITextField, didChangeText text: Stringจะถูกรวมเข้าด้วยกัน แต่ ... (ทำให้คนที่ Apple ดูสกปรก)
Brandon A

394

คำตอบของ XenElement คือจุดที่

ข้างต้นสามารถทำได้ในตัวสร้างส่วนต่อประสานด้วยโดยการคลิกขวาที่ UITextField และลาก "Editing Changed" ส่งเหตุการณ์ไปยังคลาสย่อยของคุณ

เหตุการณ์การเปลี่ยนแปลง UITextField


2
อาจเป็นเรื่องง่าย แต่หลังจากการค้นหาประมาณ 10-15 นาทีฉันไม่ได้ค้นพบความเป็นไปได้นี้จนกว่าจะพบคำตอบโดยบังเอิญ มี +1 อีกจากฉัน ยินดีที่ได้รับการลงคะแนนอย่างสูงสำหรับคำถามเช่นนี้
Mark Amery

ฉันเพิ่งตรวจสอบใน 6.3 และมันอยู่ที่นั่น นี่คือ UITextView และคลิกขวาและดู "การแก้ไขการเปลี่ยนแปลง"
William T.

4
ทำไมบนโลกถึงมีชื่อว่า Editing Changed? บ้า! ขอบคุณสำหรับการแก้ปัญหาแม้ว่า :-)
malhal

3
เพราะเหตุการณ์ถูกเรียกเมื่อแก้ไขการเปลี่ยนแปลงในขณะที่การเปลี่ยนแปลงมูลค่าเกิดขึ้นเมื่อฟิลด์ข้อความเสร็จสิ้นการแก้ไขเช่นลาออกการตอบกลับครั้งแรก UITextFieldTextDidChangeNotification เป็นการแจ้งเตือน UITextField ในขณะที่ UIControlEventValueChanged ถูกใช้งานโดย UIControl ซึ่งคลาสย่อย UIButton
Camsoft

2
ฉันสังเกตเห็นว่าสิ่งนี้ไม่ทำงานเมื่อแท็บผู้ใช้ออกจากฟิลด์ข้อความและข้อความแก้ไขอัตโนมัติจะแทนที่เนื้อหา
noobular

136

เพื่อตั้งฟังเหตุการณ์:

[self.textField addTarget:self action:@selector(textFieldDidChange:) forControlEvents:UIControlEventEditingChanged];

ฟังจริง:

- (void)textFieldDidChange:(UITextField *)textField {
    NSLog(@"text changed: %@", textField.text);
}

เย็น. ฉันชอบวิธีนี้เพราะฉันต้องการใช้ textField-change-Listen ในคลาสพื้นฐานของ ViewController ซึ่งเป็น TextFieldDelegate อยู่แล้ว วิธีนี้ฉันสามารถเพิ่มเป้าหมาย: baseControllerMethod สำหรับ (ฟิลด์ข้อความในการดูย่อย) เหมือนเครื่องราง ขอบคุณ!
HBublitz

87

สวิฟท์:

yourTextfield.addTarget(self, action: #selector(textFieldDidChange(textField:)), for: .editingChanged)

จากนั้นใช้ฟังก์ชันการเรียกกลับ:

@objc func textFieldDidChange(textField: UITextField){

print("Text changed")

}

2
ทำงานให้ฉันฉันได้ลองแล้ว แต่ไม่ได้ตระหนักถึงฟังก์ชั่นที่ต้องการอาร์กิวเมนต์ฟิลด์ข้อความ หากสิ่งนี้ไม่ได้ผลสำหรับคุณตรวจสอบให้แน่ใจว่าตัวเลือกของคุณมีอาร์กิวเมนต์สำหรับฟิลด์ข้อความที่จะส่งผ่าน (แม้ว่าคุณจะไม่ได้ใช้)
werm098

เพิ่ม _ ก่อน textField ใน textFieldDidChange เช่นนี้: func textFieldDidChange (textField: UITextField) {... }
Makalele

30

ตามที่ระบุไว้ที่นี่: เหตุการณ์ UITextField เปลี่ยนแปลงข้อความมันก็ดูเหมือนว่าเป็นของ iOS 6 (iOS 6.0 และ 6.1 ตรวจสอบ) มันเป็นไปไม่ได้ที่จะตรวจสอบอย่างเต็มที่การเปลี่ยนแปลงในวัตถุเพียงโดยการสังเกตUITextFieldUITextFieldTextDidChangeNotification

ดูเหมือนว่าจะมีการติดตามเฉพาะการเปลี่ยนแปลงที่ทำโดยแป้นพิมพ์ iOS ในตัวเท่านั้น ซึ่งหมายความว่าหากคุณเปลี่ยนUITextFieldวัตถุเพียงแค่เรียกสิ่งนี้: myUITextField.text = @"any_text"คุณจะไม่ได้รับแจ้งเกี่ยวกับการเปลี่ยนแปลงใด ๆ เลย

ฉันไม่รู้ว่านี่เป็นข้อผิดพลาดหรือมีจุดประสงค์ ดูเหมือนว่าเป็นข้อผิดพลาดเนื่องจากฉันไม่พบคำอธิบายที่สมเหตุสมผลในเอกสารประกอบ นี่คือที่ระบุยังที่นี่: เหตุการณ์ UITextField เปลี่ยนแปลงข้อความ

"ทางออก" ของฉันสำหรับสิ่งนี้คือการโพสต์การแจ้งเตือนด้วยตัวเองสำหรับการเปลี่ยนแปลงทุกครั้งที่ฉันทำกับฉันUITextField(หากการเปลี่ยนแปลงนั้นทำได้โดยไม่ต้องใช้แป้นพิมพ์ iOS ในตัว) บางสิ่งเช่นนี้

myUITextField.text = @"I'm_updating_my_UITextField_directly_in_code";

NSNotification *myTextFieldUpdateNotification  = 
  [NSNotification notificationWithName:UITextFieldTextDidChangeNotification
                  object:myUITextField];

[NSNotificationCenter.defaultCenter 
  postNotification:myTextFieldUpdateNotification];

วิธีนี้คุณจะมั่นใจ 100% ว่าคุณจะได้รับการแจ้งเตือนแบบเดียวกันเมื่อคุณเปลี่ยน.textคุณสมบัติของUITextFieldวัตถุของคุณไม่ว่าจะเป็นเมื่อคุณอัปเดต "ด้วยตนเอง" ในรหัสของคุณหรือผ่านแป้นพิมพ์ iOS ในตัว

เป็นสิ่งสำคัญที่จะต้องพิจารณาว่าเนื่องจากนี่ไม่ใช่พฤติกรรมที่ทำเป็นเอกสารแนวทางนี้อาจนำไปสู่การแจ้งเตือนที่ได้รับ 2 ครั้งสำหรับการเปลี่ยนแปลงในUITextFieldวัตถุของคุณ ขึ้นอยู่กับความต้องการของคุณ (สิ่งที่คุณทำจริงเมื่อมีUITextField.textการเปลี่ยนแปลง) สิ่งนี้อาจไม่สะดวกสำหรับคุณ

แนวทางที่แตกต่างกันเล็กน้อยคือการโพสต์การแจ้งเตือนที่กำหนดเอง (นี่คือด้วยชื่อที่กำหนดเองนอกเหนือจากUITextFieldTextDidChangeNotification) หากคุณจำเป็นต้องรู้ว่าการแจ้งเตือนนั้นเป็นของคุณหรือ "ที่ทำด้วย iOS"

แก้ไข:

ฉันเพิ่งพบวิธีที่แตกต่างซึ่งฉันคิดว่าน่าจะดีกว่า:

สิ่งนี้เกี่ยวข้องกับคุณสมบัติKey-Value Observing (KVO)ของ Objective-C ( http://developer.apple.com/library/ios/#documentation/cocoa/conceptual/KeyValueObserving/KeyValueObserving.html#//apple_ref/doc/uid / 10000177-BCICJDHA )

โดยทั่วไปคุณลงทะเบียนตัวเองในฐานะผู้สังเกตการณ์ของอสังหาริมทรัพย์และหากคุณสมบัตินี้เปลี่ยนแปลงคุณจะได้รับแจ้งเกี่ยวกับอสังหาริมทรัพย์ "หลักการ" นั้นค่อนข้างคล้ายกับวิธีการNSNotificationCenterทำงานเป็นข้อได้เปรียบหลักที่วิธีการนี้ทำงานโดยอัตโนมัติเช่นเดียวกับ iOS 6 (ไม่มีการบิดพิเศษใด ๆ เช่นต้องโพสต์การแจ้งเตือนด้วยตนเอง)

สำหรับUITextField-scenario ของเรามันใช้งานได้ดีถ้าคุณเพิ่มรหัสนี้ลงไปตัวอย่างเช่นของคุณUIViewControllerที่มีฟิลด์ข้อความ:

static void *myContext = &myContext;

- (void)viewDidLoad {
  [super viewDidLoad];

  //Observing changes to myUITextField.text:
  [myUITextField addObserver:self forKeyPath:@"text"
    options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld 
    context:myContext];

}

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object 
change:(NSDictionary *)change context:(void *)context {

  if(context == myContext) {
    //Here you get notified every time myUITextField's "text" property is updated
    NSLog(@"New value: %@ - Old value: %@",
      [change objectForKey:NSKeyValueChangeNewKey],
      [change objectForKey:NSKeyValueChangeOldKey]);
  }
  else 
    [super observeValueForKeyPath:keyPath ofObject:object 
      change:change context:context];

}

ให้เครดิตกับคำตอบนี้เกี่ยวกับการจัดการ "บริบท": https://stackoverflow.com/a/12097161/2078512

หมายเหตุ: ดูเหมือนว่าขณะที่คุณอยู่ในขั้นตอนของการแก้ไขUITextFieldที่มีแป้นพิมพ์ในตัว iOS ของคุณ, สถานที่ให้บริการ "ข้อความ" ของช่องข้อความจะไม่ปรับปรุงด้วยจดหมายทุกฉบับใหม่พิมพ์ / ลบออก แต่วัตถุฟิลด์ข้อความจะได้รับการอัปเดต "โดยรวม" หลังจากคุณลาออกสถานะการตอบกลับแรกของฟิลด์ข้อความ


5
ทำไมต้องทำเช่นนี้เพียงใช้วิธีการตั้งเป้าหมายจากคำตอบของ XenElement หากคุณต้องการโค้ดสิบบรรทัดทำสิ่งที่ "ควร" ให้เรียบง่ายคุณอาจทำผิด
jrturton

6
ดูเหมือนว่าจะเป็นพฤติกรรมที่ตั้งใจไว้ ไม่มีวิธีการมอบหมายอื่น ๆ (เช่นการเลื่อนการเลือก) ถูกเรียกสำหรับเหตุการณ์ที่เกิดจากรหัส
jrturton

1
โปรดทราบว่าUIKit ไม่รับประกันว่าจะเป็นไปตามมาตรฐาน KVOดังนั้นโซลูชัน KVO จึงไม่จำเป็นต้องทำงาน
ปาง

@jrturton เกี่ยวกับคำถาม "ทำไม" ของคุณมันเป็นเรื่องธรรมดาที่ในชั้นเรียนอื่น (อาจจะเป็นของตกแต่งภาพเคลื่อนไหวหรือสิ่งที่คล้ายกัน) คุณต้องตอบสนองต่อสิ่งที่เกิดขึ้นในฟิลด์ข้อความ
Fattie

27

เราสามารถกำหนดค่าได้อย่างง่ายดายStoryboardCTRL ลาก@IBActionและเปลี่ยนเหตุการณ์ดังต่อไปนี้

ป้อนคำอธิบายรูปภาพที่นี่


14

ที่นี่ในรุ่นที่รวดเร็วเหมือนกัน

textField.addTarget(self, action: "textFieldDidChange:", forControlEvents: UIControlEvents.EditingChanged)

func textFieldDidChange(textField: UITextField) {

}

ขอบคุณ


12

ฉันแก้ไขปัญหาการเปลี่ยนพฤติกรรมของ shouldChangeChractersInRange หากคุณคืนค่า NO การเปลี่ยนแปลงจะไม่ถูกนำไปใช้โดย iOS ภายในแทนคุณมีโอกาสที่จะเปลี่ยนแปลงด้วยตนเองและดำเนินการใด ๆ หลังจากการเปลี่ยนแปลง

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
    //Replace the string manually in the textbox
    textField.text = [textField.text stringByReplacingCharactersInRange:range withString:string];
    //perform any logic here now that you are sure the textbox text has changed
    [self didChangeTextInTextField:textField];
    return NO; //this make iOS not to perform any action
}

3
ปัญหาเกี่ยวกับวิธีแก้ไขปัญหานี้คือ: ตำแหน่งเคอร์เซอร์จะถูกตั้งค่าเป็นจุดสิ้นสุดของฟิลด์ (ทันทีที่คุณทำ textField.text = ... ) ดังนั้นหากผู้ใช้ต้องการแก้ไขตัวอักษรที่อยู่ตรงกลางสนามจากนั้นกดปุ่มแต่ละครั้งเคอร์เซอร์ของพวกเขาจะไปยังจุดสิ้นสุดของฟิลด์ ลองและดู
FranticRock

จุดดี @Alex แต่ง่ายต่อการแก้ไข เพียงคำนวณค่าผลลัพธ์ใน NSString แบบโลคัลและส่งผ่านไปยังเมธอด didChangeTextInTextField: toText: ของคุณแล้วส่งคืน YES เพื่อให้ iOS ทำการอัปเดต
jk7

11

ทดสอบ Swift Version แล้ว:

//Somewhere in your UIViewController, like viewDidLoad(){ ... }
self.textField.addTarget(
        self, 
        action: #selector(SearchViewController.textFieldDidChange(_:)),
        forControlEvents: UIControlEvents.EditingChanged
)

พารามิเตอร์อธิบาย:

self.textField //-> A UITextField defined somewhere in your UIViewController
self //-> UIViewController
.textFieldDidChange(_:) //-> Can be named anyway you like, as long as it is defined in your UIViewController

จากนั้นเพิ่มวิธีการที่คุณสร้างไว้ด้านบนในUIViewController:

//Gets called everytime the text changes in the textfield.
func textFieldDidChange(textField: UITextField){

    print("Text changed: " + textField.text!)

}

7

สวิฟท์ 4

func addNotificationObservers() {

    NotificationCenter.default.addObserver(self, selector: #selector(textFieldDidChangeAction(_:)), name: .UITextFieldTextDidChange, object: nil)

}

@objc func textFieldDidChangeAction(_ notification: NSNotification) {

    let textField = notification.object as! UITextField
    print(textField.text!)

}

5

สำหรับ Swift 3.0:

let textField = UITextField()

textField.addTarget(
    nil,
    action: #selector(MyClass.textChanged(_:)),
    for: UIControlEvents.editingChanged
)

ใช้คลาสที่ชอบ:

class MyClass {
    func textChanged(sender: Any!) {

    }
}

4

เวอร์ชั่น Swift 3

yourTextField.addTarget(self, action: #selector(YourControllerName.textChanges(_:)), for: UIControlEvents.editingChanged)

และรับการเปลี่ยนแปลงที่นี่

func textChanges(_ textField: UITextField) {
    let text = textField.text! // your desired text here
    // Now do whatever you want.
}

หวังว่ามันจะช่วย


2

คุณควรใช้การแจ้งเตือนเพื่อแก้ไขปัญหานี้เนื่องจากวิธีอื่นจะฟังกล่องอินพุตไม่ใช่อินพุตจริงโดยเฉพาะเมื่อคุณใช้วิธีการอินพุตภาษาจีน ใน viewDidload

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textFiledEditChanged:)
                                                 name:@"UITextFieldTextDidChangeNotification"
                                               object:youTarget];

แล้วก็

- (void)textFiledEditChanged:(NSNotification *)obj {
UITextField *textField = (UITextField *)obj.object;
NSString *toBestring = textField.text;
NSArray *currentar = [UITextInputMode activeInputModes];
UITextInputMode *currentMode = [currentar firstObject];
if ([currentMode.primaryLanguage isEqualToString:@"zh-Hans"]) {
    UITextRange *selectedRange = [textField markedTextRange];
    UITextPosition *position = [textField positionFromPosition:selectedRange.start offset:0];
    if (!position) {
        if (toBestring.length > kMaxLength)
            textField.text =  toBestring;
} 

}

ในที่สุดคุณทำงานจะทำ


2

สวิฟท์ 3.1:

ตัวเลือก: ClassName.MethodName

  cell.lblItem.addTarget(self, action: #selector(NewListScreen.fieldChanged(textfieldChange:)), for: .editingChanged)

  func fieldChanged(textfieldChange: UITextField){

    }

2

เวอร์ชั่น Swift 3:

class SomeClass: UIViewController, UITextFieldDelegate { 

   @IBOutlet weak var aTextField: UITextField!


    override func viewDidLoad() {
        super.viewDidLoad()

        aTextField.delegate = self
        aTextField.addTarget(self, action: #selector(SignUpVC.textFieldDidChange), for: UIControlEvents.editingChanged)        
    }

   func textFieldDidChange(_ textField: UITextField) {

       //TEXT FIELD CHANGED..SECRET STUFF

   }

}

อย่าลืมตั้งตัวแทน


ฉันมีเขตข้อมูลข้อความ 6 ตัวในตัวควบคุมมุมมองของฉันและฉันต้องการตรวจสอบว่าเขตข้อมูลข้อความสุดท้ายถูกเปลี่ยนการพิมพ์ ("เปลี่ยนเขตข้อมูลข้อความล่าสุด!") คุณช่วยได้ไหม?
Saeed Rahmatolahi

ก่อนอื่นสร้าง Iboutlet สำหรับฟิลด์ข้อความของคุณ จากนั้นตั้งค่าผู้รับมอบสิทธิ์และเพิ่มเป้าหมายเช่นฉันแสดงในคำตอบของฉัน ในฟังก์ชั่นผู้มอบหมาย textFieldDidChange เพิ่มสิ่งนี้: "ถ้า textField == yourLastTextField {พิมพ์ (" เปลี่ยนฟิลด์ข้อความสุดท้าย! ")} ตอนนี้ฉันไม่สามารถเข้าถึงคอมพิวเตอร์ของฉันได้ฉันจะทำให้ความคิดเห็นนี้อ่านง่ายขึ้นเมื่อฉัน ไปที่คอมพิวเตอร์ของฉัน
โจเซฟฟรานซิส

2

ด้วยการปิด:

   class TextFieldWithClosure: UITextField {
    var targetAction: (() -> Void)? {
        didSet {
            self.addTarget(self, action: #selector(self.targetSelector), for: .editingChanged)
        }
    }

    func targetSelector() {
        self.targetAction?()
    }
    }

และการใช้

textField.targetAction? = {
 // will fire on text changed
 }

2
  1. โซลูชันของ KVO ไม่ทำงาน

KVO ไม่ทำงานใน iOS สำหรับการควบคุม: http://stackoverflow.com/a/6352525/1402846 https://developer.apple.com/library/archive/documentation/General/Conceptual/DevPedia-CocoaCore/KVO.html

  1. ในชั้นเรียนการสังเกตคุณทำสิ่งนี้:

ระบุว่าคุณทราบมุมมองข้อความที่คุณต้องการรับชม:

var watchedTextView: UITextView!

ทำเช่นนี้:

NotificationCenter.default.addObserver(
    self,
    selector: #selector(changed),
    name: UITextView.textDidChangeNotification,
    object: watchedTextView)

อย่างไรก็ตามโปรดระวัง:

  • เป็นไปได้ว่าคุณต้องการโทรหาเพียงครั้งเดียวดังนั้นอย่าโทรไปหาเช่นlayoutSubviews

  • มันค่อนข้างยากที่จะรู้ว่าเมื่อใดควรโทรหามันในระหว่างกระบวนการนำขึ้น มันจะขึ้นอยู่กับสถานการณ์ของคุณ น่าเสียดายที่ไม่มีวิธีแก้ปัญหาแบบล็อคอินมาตรฐาน

  • ตัวอย่างเช่นคุณมักจะไม่สามารถโทรหาได้ในinitเวลาเนื่องจากแน่นอนwatchedTextViewอาจยังไม่มี

.

  1. ปัญหาต่อไปคือ ...

ไม่มีการแจ้งเตือนจะถูกเรียกเมื่อข้อความที่มีการเปลี่ยนแปลงโปรแกรม

นี่เป็นสิ่งที่สร้างความรำคาญให้กับวิศวกรรม iOS

การควบคุมเพียงไม่สิ้นสุดของเรื่อง - เรียกการแจ้งเตือนเมื่อคุณสมบัติ. text มีการเปลี่ยนแปลงโดยทางโปรแกรม

นี่เป็นเรื่องที่น่ารำคาญอย่างแน่นอนเพราะเห็นได้ชัดว่า - ทุกแอปที่เคยทำจะตั้งค่าข้อความโดยทางโปรแกรมเช่นการล้างฟิลด์หลังจากผู้ใช้โพสต์ ฯลฯ

คุณต้อง subclass มุมมองข้อความ (หรือตัวควบคุมที่คล้ายกัน) เช่นนี้

class NonIdioticTextView: UIITextView {

    override var text: String! {
        // boilerplate code needed to make watchers work properly:
        get {
            return super.text
        }
        set {
            super.text = newValue
            NotificationCenter.default.post(
                name: UITextView.textDidChangeNotification,
                object: self)
        }

    }

}

(เคล็ดลับ - อย่าลืมสายด่วนต้องมาก่อน !

มีไม่มีวิธีการแก้ปัญหาที่มีอยู่เว้นแต่คุณแก้ไขการควบคุมโดย subclassing ตามที่ปรากฏอยู่เหนือ นั่นเป็นทางออกเดียว

โปรดทราบว่าการแจ้งเตือน

UITextView.textDidChangeNotification

ผลลัพธ์ใน

func textViewDidChangeSelection(_ textView: UITextView) 

ถูกเรียกว่า

( ไม่ใช่ textViewDidChange )


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



- (void) didChangeTextViewText {
 //do something
}

0

สิ่งหนึ่งคือคุณอาจมีหลาย UITextFields ดังนั้นให้พวกเขาแท็กแล้วคุณสามารถเปิดแท็ก ต่อไปนี้เป็นวิธีตั้งค่าผู้สังเกตการณ์ในชั้นเรียนใด ๆ

private func setupTextFieldNotification() {
    NotificationCenter.default.addObserver(forName: UITextField.textDidChangeNotification, object: nil, queue: OperationQueue.main) { (notification) in
        if let textField = notification.object as? UITextField, textField.tag == 100, let text = textField.text {
            print(#line, text)
        }
    }
}

deinit {
    NotificationCenter.default.removeObserver(self)
}

-1

เวอร์ชั่น Swift 4

การใช้ Key-Value Observing Notify objects เกี่ยวกับการเปลี่ยนแปลงคุณสมบัติของวัตถุอื่น

var textFieldObserver: NSKeyValueObservation?

textFieldObserver = yourTextField.observe(\.text, options: [.new, .old]) { [weak self] (object, changeValue) in
  guard let strongSelf = self else { return }
  print(changeValue)
}

ความคิดที่ดี. คุณสามารถห่อสิ่งนี้ในบริบทและแจ้งให้เราทราบได้ไหม?
Revanth Kausikan

1
นี่เป็นความผิดที่น่าเสียดายอย่างยิ่ง KVO ไม่ทำงานใน iOS สำหรับการควบคุม: stackoverflow.com/a/6352525/1402846 developer.apple.com/library/archive/documentation/General/
......
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.