UITextField가 변경 될 때 어떻게 확인합니까?


290

텍스트 필드가 변경되는 시점을 확인하려고하는데 textView에 사용 된 기능과 동일합니다. textViewDidChange지금 까지이 작업을 수행했습니다.

  func textFieldDidBeginEditing(textField: UITextField) {
        if self.status.text == "" && self.username.text == "" {
            self.topRightButton.enabled = false
        } else {   
            self.topRightButton.enabled = true
        }
    }

어떤 종류의 작품이지만 topRightButton텍스트 필드를 누르 자마자 활성화되어 있습니까? 텍스트를 실제로 입력 할 때만 활성화하고 싶습니다.

답변:


739

빠른

스위프트 4.2

textfield.addTarget(self, action: #selector(ViewController.textFieldDidChange(_:)), for: .editingChanged)

@objc func textFieldDidChange(_ textField: UITextField) {

}

스위프트 3 & 스위프트 4.1

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

func textFieldDidChange(_ textField: UITextField) {

}

스위프트 2.2

textField.addTarget(self, action: #selector(ViewController.textFieldDidChange(_:)), forControlEvents: UIControlEvents.EditingChanged)

func textFieldDidChange(textField: UITextField) {
    //your code
}

목표 -C

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

textFieldDidChange 메소드는

-(void)textFieldDidChange :(UITextField *) textField{
    //your code
}

이것은 나를 위해 충돌하고 이유를 이해하지 못합니다.
Levi Roberts

1
여러 번 확인했습니다. 델리게이트는 바로 내부에 설정됩니다 viewDidLoad. 행동은 같은 편지에 대한 편지입니다. 키보드 버튼을 누르 자마자 앱이 다운됩니다. 편집 : 알아 냈습니다! 작업 내부에 세미콜론이 없습니다. 함수 이름과 동일해야한다고 가정했습니다.
Levi Roberts

@FawadMasud Xcode 7을 사용하는 iOS 9의 Swift 2.0에서는 현재 아무것도하지 않습니다 .Xcode 7은 감가 상각되었거나 현재 해결 방법을 알고 있습니까?
Cody Weaver

1
@bibscy 예, 뷰 안의 모든 텍스트 필드를 반복해야합니다.
Fawad Masud

1
Swift 4.2의 경우 : Texttfield.addTarget (자체, 액션 : #selector (ViewControllerr.textFieldDidChange (_ :)), for : UIControl.Event.editingChanged)
종료

128

인터페이스 빌더에서이 연결을 작성할 수 있습니다.

  1. 스토리 보드에서 화면 상단의 보조 편집기 (가운데에 두 개의 원)를 클릭하십시오. 어시스턴트 에디터 선택

  2. 인터페이스 빌더에서 텍스트 필드를 Ctrl + 클릭하십시오.

  3. 보조자보기의 EditingChanged에서 뷰 컨트롤러 클래스 내부로 드래그하십시오. 연결하기

  4. 함수 이름을 지정하고 (예 : "textDidChange") 연결을 클릭하십시오. 명명 기능


3
이것은 특히 별도의 데이터 소스로 관리되는 tableViewCell에서 UITextField를 처리하는 경우에 훌륭한 솔루션입니다. 이 접근 방식은 viewController가 직접 응답 할 수 있도록합니다 (따라서 데이터 소스가 응답하고 조치를 위임 할 필요가 없습니다).
wuf810

1
대단한-자극적 인 문제에 대한 간단한 해결책. 여러 텍스트 필드를 연결할 수 있습니다
Jeremy Andrews

1
추가 @objc func를 제거하기 때문에 아마도 위의 것보다 더 나은 대답 일 것입니다.
Matthew Bradshaw

좋은 생각입니다, DidEndEditing 이벤트를 사용합니다
Puji Wahono

이것이 가장 좋은 해결책입니다. 감사합니다 @rmooney!
Jonathan

63

스위프트 5.0

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

처리 방법 :

@objc func textFieldDidChange(_ textField: UITextField) {

}

스위프트 4.0

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

처리 방법 :

@objc func textFieldDidChange(_ textField: UITextField) {

}

스위프트 3.0

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

처리 방법 :

func textFieldDidChange(textField: UITextField) { 

}

29

내가 지금까지 처리 한 방식 : UITextFieldDelegate

func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool
{
    // text hasn't changed yet, you have to compute the text AFTER the edit yourself
    let updatedString = (textField.text as NSString?)?.stringByReplacingCharactersInRange(range, withString: string)

    // do whatever you need with this updated string (your code)


    // always return true so that changes propagate
    return true
}

스위프트 4 버전

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
    let updatedString = (textField.text as NSString?)?.replacingCharacters(in: range, with: string)
    return true
}

1
텍스트 필드가 비어 있고 사용자가 백 스페이스를 클릭하면 호출되지 않습니다.
Matthew Mitchell

14

스위프트 3

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

7

스위프트 3.0.1+ (다른 신속한 3.0 답변 중 일부는 최신이 아닙니다)

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

func textFieldDidChange(_ textField: UITextField) {

}

6

textField (_ : shouldChangeCharactersIn : replacementString :) 은 모든 키 누름을 확인하려면 Xcode 8, Swift 3에서 저에게 효과적이었습니다 .

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

    // Whatever code you want to run here.
    // Keep in mind that the textfield hasn't yet been updated,
    // so use 'string' instead of 'textField.text' if you want to
    // access the string the textfield will have after a user presses a key

    var statusText = self.status.text
    var usernameText = self.username.text

    switch textField{
    case self.status:
        statusText = string
    case self.username:
        usernameText = string
    default:
        break
    }

    if statusText == "" && usernameText == "" {
        self.topRightButton.enabled = false
    } else {   
        self.topRightButton.enabled = true
    }

    //Return false if you don't want the textfield to be updated
    return true
}

5

스위프트 4

UITextFieldDelegate를 준수하십시오 .

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
    // figure out what the new string will be after the pending edit
    let updatedString = (textField.text as NSString?)?.replacingCharacters(in: range, with: string)

    // Do whatever you want here


    // Return true so that the change happens
    return true
}

4

UITextFieldDelegate에서이 대리자 메서드를 사용할 수 있습니다. 모든 캐릭터 변경과 함께 발생합니다.

(Objective C) textField:shouldChangeCharactersInRange:replacementString:
(Swift) textField(_:shouldChangeCharactersInRange:replacementString:)

그러나이 변경은 변경 전에 이루어집니다 (실제로 여기에서 true를 반환하는 경우에만 변경이 이루어집니다).


1
이 방법을 시도해 보았을 때 어떻게 작성해야합니까? 텍스트 필드가 활성화되면 텍스트가 실제로 변경되면 한 번만 변경되는 동일한 솔루션을 찾으십시오.

위의 delegate 메소드를 구현하면 텍스트를 변경할 때마다 발생합니다. 이 코드 만 추가하면됩니다. self.textfield.delegate = self
Abubakr Dar

나 에게이 방법은 텍스트 필드가 메서드 내부에 비어 있는지 확인할 수 없기 때문에 작동하지 않았습니다. 주로 텍스트 필드가 변경 될 수 있는지에 따라 true / false를 반환하기 때문입니다. 따라서 텍스트 필드가 비게되기 전에 이벤트가 시작됩니다.
Levi Roberts

@LeviRoberts,이 메소드 안에 텍스트 필드에 대한 참조가 있습니다. 따라서 textfield.text가 비어 있는지 확인할 수 있습니다.
Abubakr Dar

당신은 이해하지 못하는 것 같습니다. 비어있는 경우, .isEmpty이 메소드가 true를 돌려 줄 기회가있을 때까지 메소드는 true와 동일하지 않습니다. 텍스트 필드를 변경해야한다는 것을 앱에 알려줍니다.
Levi Roberts

3

아마도 RxSwift?

필요한 것

pod 'RxSwift',    '~> 3.0'
pod 'RxCocoa',    '~> 3.0'

수입을 분명히 추가하다

import RxSwift
import RxCocoa

그래서 너는 textfield : UITextField

let observable: Observable<String?> = textField.rx.text.asObservable()
observable.subscribe(
            onNext: {(string: String?) in
                print(string!)
        })

U에는 다른 3 가지 방법이 있습니다.

  1. onError
  2. 완료
  3. onDisposed
  4. 다음에

텍스트 필드가 첫 번째 응답자가 된 시점이 아니라 실제 변경 이벤트 만 수신하려면 텍스트에서 distinctUntilChanged를 사용해야합니다.
RealNmae

1

스위프트 4

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

@objc func textIsChanging(_ textField:UITextField) {

 print ("TextField is changing")

}

사용자가 완전히 입력 한 후에 변경하려면 키보드를 닫거나 Enter 키를 누르면 호출됩니다.

textField.addTarget(self, action: #selector(textDidChange), for: UIControlEvents.editingDidEnd)

 @objc func textDidChange(_ textField:UITextField) {

       print ("TextField did changed") 
 }

1
txf_Subject.addTarget(self, action:#selector(didChangeFirstText), for: .editingChanged)

@objc func didChangeText(textField:UITextField) {
    let str = textField.text
    if(str?.contains(" "))!{
        let newstr = str?.replacingOccurrences(of: " ", with: "")
        textField.text = newstr
    }
}

@objc func didChangeFirstText(textField:UITextField) {
    if(textField.text == " "){
        textField.text = ""
    }
}

1

다음 단계를 따라야합니다.

  1. 텍스트 필드에 대한 아울렛 참조 만들기
  2. 컨트롤러 클래스에 AssignUITextFieldDelegate
  3. yourTextField.delegate를 구성하십시오.
  4. 필요한 기능을 구현하십시오

샘플 코드 :

import UIKit

class ViewController: UIViewController, UITextFieldDelegate {

    @IBOutlet var yourTextFiled : UITextField!

    override func viewDidLoad() {
        super.viewDidLoad()

        yourTextFiled.delegate = self
    }


    func textFieldDidEndEditing(_ textField: UITextField) {
        // your code
    }

    func textFieldShouldReturn(_ textField: UITextField) -> Bool {
        // your code
    }

    .
    .
    .
}

0

Swift 3을textField text change listener 사용하여 추가하는 방법입니다. .

수업을 다음과 같이 선언하십시오. UITextFieldDelegate

override func viewDidLoad() {
    super.viewDidLoad()

    textField.delegate = self

    textField.addTarget(self, action: #selector(UITextFieldDelegate.textFieldShouldEndEditing(_:)), for: UIControlEvents.editingChanged)
}

그런 다음 전통적으로 textFieldShouldEndEditing 함수를 추가하십시오.

func textFieldShouldEndEditing(_ textField: UITextField) -> Bool { // do stuff
        return true 
}

0

스위프트 4.2

이것을 viewDidLoad에 작성하십시오

// to detect if TextField changed
TextField.addTarget(self, action: #selector(textFieldDidChange(_:)),
                                   for: UIControl.Event.editingChanged)

이것을 view 외부에 작성하십시오

@objc func textFieldDidChange(_ textField: UITextField) {
    // do something
}

UIControl.Event.editingDidBegin 또는 감지하려는 항목으로 이벤트를 변경할 수 있습니다.


0

SwiftUI 솔루션에 관심이있는 경우이 기능이 유용합니다.

 TextField("write your answer here...",
            text: Binding(
                     get: {
                        return self.query
                       },
                     set: { (newValue) in
                        self.fetch(query: newValue) // any action you need
                                return self.query = newValue
                      }
            )
  )

나는 그것이 내 생각이 아니라고 말해야한다. 나는이 블로그에서 그것을 읽었다 : SwiftUI 바인딩 : 매우 간단한 트릭


0

addTarget을 UITextField에 바인딩 할 수없는 경우 위에서 제안한대로 addTarget을 바인딩하고 shouldChangeCharactersIn 메소드 끝에 실행할 코드를 삽입하는 것이 좋습니다.

nameTextField.addTarget(self, action: #selector(RegistrationViewController.textFieldDidChange(_:)), for: .editingChanged)

@objc func textFieldDidChange(_ textField: UITextField) {
    if phoneNumberTextField.text!.count == 17 && nameTextField.text!.count > 0 {
        continueButtonOutlet.backgroundColor = UIColor(.green)
    } else {
        continueButtonOutlet.backgroundColor = .systemGray
    }
}

그리고 shouldChangeCharacters에서 func를 호출하십시오.

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

    guard let text = textField.text else {
        return true
    }
    let lastText = (text as NSString).replacingCharacters(in: range, with: string) as String

    if phoneNumberTextField == textField {
        textField.text = lastText.format("+7(NNN)-NNN-NN-NN", oldString: text)
        textFieldDidChange(phoneNumberTextField)
        return false
    }
    return true
}

-1

스위프트 4

viewDidLoad ()에서 :

    //ADD BUTTON TO DISMISS KEYBOARD

    // Init a keyboard toolbar 
    let toolbar = UIView(frame: CGRect(x: 0, y: view.frame.size.height+44, width: view.frame.size.width, height: 44))
    toolbar.backgroundColor = UIColor.clear

    // Add done button
    let doneButt = UIButton(frame: CGRect(x: toolbar.frame.size.width - 60, y: 0, width: 44, height: 44))
    doneButt.setTitle("Done", for: .normal)
    doneButt.setTitleColor(MAIN_COLOR, for: .normal)
    doneButt.titleLabel?.font = UIFont(name: "Titillium-Semibold", size: 13)
    doneButt.addTarget(self, action: #selector(dismissKeyboard), for: .touchUpInside)
    toolbar.addSubview(doneButt)

    USDTextField.inputAccessoryView = toolbar

이 기능을 추가하십시오 :

    @objc func dismissKeyboard() {
      //Causes the view (or one of its embedded text fields) to resign the first responder status.
      view.endEditing(true)
    }

-1

새로운 커스텀 클래스 MaterialTextfield.swift 생성

class MaterialTextfield: UITextField,UITextFieldDelegate {

var bottomBorder = UIView()
var shouldShowEditing = false

override func awakeFromNib() {

    // Setup Bottom-Border

    self.delegate = self
    self.translatesAutoresizingMaskIntoConstraints = false

    bottomBorder = UIView.init(frame: CGRect(x: 0, y: 0, width: 0, height: 0))
    bottomBorder.backgroundColor = UIColor(rgb: 0xE2DCD1) // Set Border-Color
    bottomBorder.translatesAutoresizingMaskIntoConstraints = false

    addSubview(bottomBorder)

    bottomBorder.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true
    bottomBorder.leftAnchor.constraint(equalTo: leftAnchor).isActive = true
    bottomBorder.rightAnchor.constraint(equalTo: rightAnchor).isActive = true
    bottomBorder.heightAnchor.constraint(equalToConstant: 1).isActive = true // Set Border-Strength

}
@IBInspectable var hasError: Bool = false {
    didSet {
        if (hasError) {
            bottomBorder.backgroundColor = UIColor.red//error color
        } else {
            bottomBorder.backgroundColor = UIColor(rgb: 0xE2DCD1)//passive color
        }

    }
}
@IBInspectable var showEditing: Bool = false{
    didSet {
        if (showEditing) {
            bottomBorder.backgroundColor = UIColor(rgb: 0x56B5CA)//active color
        } else {
            bottomBorder.backgroundColor = UIColor(rgb: 0xE2DCD1)//passive color
        }

    }

}

func textFieldDidBeginEditing(_ textField: UITextField) {//listen to on edit event
    showEditing = !self.showEditing
}
func textFieldDidEndEditing(_ textField: UITextField) {//listen to on end edit event
    showEditing = !self.showEditing
}

func textFieldShouldReturn(_ textField: UITextField) -> Bool {//listen to return button event
    textField.resignFirstResponder() // return button will close keyboard
    return true
}

}

모든면에서, 이것은 끔찍한 해결책입니다. 그는 단지 UITextField값이 업데이트 되었는지 확인하고 싶습니다. 이 간단한 문제를 해결하기 위해 지나치게 복잡한 클래스를 만드는 이유는 무엇입니까?
Guilherme Matuella

@GuilhermeMatuella 이것은 필드가 내가 필요하고 채워 졌는지 알 수있는 프론트 엔드 코드입니다. 동일한 문제를 해결하기위한 다른 접근 방식입니다. 이것은 기본적으로 나의 사용자 정의 자산입니다
Muhammad Asyraf
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.