iOS/Swift: как обнаружить сенсорное действие на UITextField

Я хотел бы обнаружить действие касания на UITextField.

Похоже, действие "Touch Up Inside" не запускается при касании внутри текстового поля.

12 ответов

Решение

Кажется, "Touch Up Inside" не включен для UiTextField, но "Touch Down" работает.

Таким образом, решение заключается в следующем:

myTextField.addTarget(self, action: #selector(myTargetFunction), for: UIControlEvents.touchDown)

@objc func myTargetFunction(textField: UITextField) {
    print("myTargetFunction")
}

Свифт 4:

class ViewController: UIViewController, UITextFieldDelegate {
    func textFieldDidBeginEditing(_ textField: UITextField) {
        if textField == myTextField {
            print("You edit myTextField")
        }
    }
}

Это функция делегата.

Вот Swfit:

и вам не нужно использовать "touchUpInside", просто используйте методы делегата следующим образом:

Сделайте ваш контроллер View делегатом:

class ViewController: UIViewController, UITextFieldDelegate{

func textFieldDidBeginEditing(textField: UITextField) -> Bool {
    if textField == myTextField {
        return true // myTextField was touched
    }
}

Вот другие методы делегата:

protocol UITextFieldDelegate : NSObjectProtocol {

    optional func textFieldShouldBeginEditing(textField: UITextField) -> Bool // return NO to disallow editing.
    optional func textFieldDidBeginEditing(textField: UITextField) // became first responder
    optional func textFieldShouldEndEditing(textField: UITextField) -> Bool // return YES to allow editing to stop and to resign first responder status. NO to disallow the editing session to end
    optional func textFieldDidEndEditing(textField: UITextField) // may be called if forced even if shouldEndEditing returns NO (e.g. view removed from window) or endEditing:YES called

    optional func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool // return NO to not change text

    optional func textFieldShouldClear(textField: UITextField) -> Bool // called when clear button pressed. return NO to ignore (no notifications)
    optional func textFieldShouldReturn(textField: UITextField) -> Bool // called when 'return' key pressed. return NO to ignore.
}

из быстрой документации:

struct UIControlEvents : RawOptionSetType {
    init(_ rawValue: UInt)
    init(rawValue: UInt)

    static var TouchDown: UIControlEvents { get } // on all touch downs
    static var TouchDownRepeat: UIControlEvents { get } // on multiple touchdowns (tap count > 1)
    static var TouchDragInside: UIControlEvents { get }
    static var TouchDragOutside: UIControlEvents { get }
    static var TouchDragEnter: UIControlEvents { get }
    static var TouchDragExit: UIControlEvents { get }
    static var TouchUpInside: UIControlEvents { get }
    static var TouchUpOutside: UIControlEvents { get }
    static var TouchCancel: UIControlEvents { get }

    static var ValueChanged: UIControlEvents { get } // sliders, etc.

    static var EditingDidBegin: UIControlEvents { get } // UITextField
    static var EditingChanged: UIControlEvents { get }
    static var EditingDidEnd: UIControlEvents { get }
    static var EditingDidEndOnExit: UIControlEvents { get } // 'return key' ending editing

    static var AllTouchEvents: UIControlEvents { get } // for touch events
    static var AllEditingEvents: UIControlEvents { get } // for UITextField
    static var ApplicationReserved: UIControlEvents { get } // range available for application use
    static var SystemReserved: UIControlEvents { get } // range reserved for internal framework use
    static var AllEvents: UIControlEvents { get }
}

UITextField не отвечает на "touchUpInside", вид справа, вы обнаружите, что это приемлемые события управления

Обновление для Swift 3

Вот код для Swift 3:

myTextField.addTarget(self, action: #selector(myTargetFunction), for: .touchDown)

Это функция:

func myTargetFunction() {
    print("It works!")
}

Я сослался на документацию UIControlEvents от Apple и придумал следующее:

Сначала добавьте UITextFieldDelegate в свой класс, затем

textBox.delegate = self
textBox.addTarget(self, action: #selector(TextBoxOn(_:)),for: .editingDidBegin)
textBox.addTarget(self, action: #selector(TextBoxOff(_:)),for: .editingDidEnd)

со следующими функциями:

func TextBoxOff(_ textField: UITextField) {
     code
         }                
}

func TextBox(_ textField: UITextField) {
    code
         }
}

Для Swift 3.1:

1) Создать распознаватель жестов:

let textViewRecognizer = UITapGestureRecognizer()

2) Добавьте обработчик к распознавателю:

textViewRecognizer.addTarget(self, action: #selector(tappedTextView(_:))) 

3) Добавьте распознаватель к вашему текстовому представлению:

textView.addGestureRecognizer(textViewRecognizer)

4) Добавьте обработчик в ваш класс:

func tappedTextView(_ sender: UITapGestureRecognizer) {
        print("detected tap!")
}

Чтобы сделать это немного яснее, эти вещи должны быть на месте. Я использовал это, чтобы сделать так, чтобы, если пользователь ввел что-то в приложение из собственного текстового поля кредита, что-либо в текстовом поле дебета было удалено.

  1. UITextFieldDelegate должен быть объявлен в контроллере View, т.е. в классе SecondViewController:
  2. Функции детектора func myDebitDetector func myCreditDetector должны быть в классе ViewController.
  3. появится debit.addTarget и credit.addtarget изнутри.

  4. @IBOutlet Слабый вар дебет: UITextField! и @IBOutlet слабый кредитный вар: UITextField! являются текстовыми полями на раскадровке и связаны с viewController.

    Класс SecondViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource, UITextFieldDelegate {

    @IBOutlet weak var credit: UITextField!
    
    @IBOutlet weak var debit: UITextField!
    
        func myDebitDetector(textfield: UITextField ){
            print("using debit")
            credit.text = ""
    
        }
    
        func myCreditDetector(textfield: UITextField) {
            print("using cedit")
            debit.text = ""
        }
    
        override func viewWillAppear(animated: Bool) {
    
    
    
            debit.addTarget(self, action: "myDebitDetector:", forControlEvents: UIControlEvents.TouchDown)
            credit.addTarget(self, action: "myCreditDetector:", forControlEvents: UIControlEvents.TouchDown)
        ....
    
        }
    }
    

Версия Swift 3.0:

textFieldClientName.addTarget(self, action: Selector(("myTargetFunction:")), for: UIControlEvents.touchDown)

Установите делегат UITextField на свой контроллер представления, реализуйте метод делегата

-(void)textField:(UITextField*)textField didBeginEditing {
   // User touched textField
}

Свифт 4.2.

Попробуйте .editingDidEnd вместо .touchDown и делегировать.

myTextField.addTarget(self, action: #selector(myTargetFunction), for: .editingDidEnd)

@objc func myTargetFunction(textField: UITextField) {
    print("textfield pressed")
}

На xamarin.iOS мне легко пользоваться:

YourTextField.WeakDelegate = this;

[...]

[Export("textFieldDidBeginEditing:")]
public void TextViewChanged(UITextField textField)
{
    if (YourTextField.Equals(textField))
        IsYourTextFileFocused = true;
}
      ** Swift 4.0 + **
Use custom action like this


YourTextField.addTarget(self, action: #selector(myTargetFunction(_:)), for: .allEditingEvents)

@IBAction private func myTargetFunction(_ sender: Any) {
        if let textField = sender as? UITextField {
            // get textField here
        }
    }
Другие вопросы по тегам