2017-05-20 22 views
1

私はプログラムでUITextViewを作成し、イベントを処理するためのデリゲートを作成しようとしています。私は追加してUITextViewを作成することができますが、UITextFieldDelegateメソッドのどれもが追加されていません。 これはなぜでしょうか?Swift:私のUITextFieldDelegateメソッドが呼び出されないのはなぜですか?

let myTextField = UITextField() 
    myTextField.frame = CGRect(x:0, y: 100, width: 300, height: 30) 
    myTextField.text = "Example Text" 

    class MyTextFieldDelegate : NSObject, UITextFieldDelegate { 
     func textFieldShouldReturn(_ textField: UITextField) -> Bool { 
      // Hide the keyboard. 
      print("should return!\n") 
      textField.resignFirstResponder() 
      return true 
     } 

     func textFieldDidEndEditing(_ textField: UITextField) { 
      print("yay!\n") 
      print(textField.text! + "\n") 
     } 

     func textFieldDidBeginEditing(_ textField: UITextField) { 
      print("yay begin!\n") 
      print(textField.text! + "\n") 
     } 

    } 

    let myTextFieldDelegate = MyTextFieldDelegate() 
    myTextField.delegate = myTextFieldDelegate 
    scrollView.addSubview(myTextField) 
+0

このコードは次のとおりです。この問題を解決するには

は、デリゲートオブジェクトを保持するために、あなたのViewControllerでプロパティを作成しますか? 'viewDidLoad()'の内部? – vacawama

+0

誰かがそれに強いポインタを持っていないので、あなたの問題は 'myTextFieldDelegate'が解放されていることです。あなたの 'ViewController'に、myTextFieldDelegateを保持するプロパティを作成して、関数が戻るときに解放されるローカル変数に代入します。 – vacawama

+0

最初は 'viewDidLoad'の内部ではなかったので、それを修正してまだ動作していませんでした。しかし、私のカスタムViewController上でmyTextFieldDelegateプロパティを作成したとき(ガベージコレクションを取得しないようにするため)出来た!ありがとうございました!あなたが答えとしてそれを置くなら、私はそれを受け入れます。 –

答えて

2

UITextFieldでは、delegateweakプロパティとして宣言されています。

vacawamaが彼のコメントで示唆するよう

、あなたは強い参照を保持しているインスタンス変数を持っているあなたのビューコントローラを必要としています。

weak var delegate: UITextFieldDelegate? { get set } 

これはdelegateインスタンスを保持していないとdelegateが解放されたときにnilに設定されることを意味します。

delegateを作成し、それをローカル変数myTextFieldDelegateに割り当てます。その変数は関数の最後に解放されるので、myTextField.delegatemyTextFieldDelegateを割り当てても、その変数は解放され、myTextField.delegateは弱いためnilに設定されます。

var myTextFieldDelegate: MyTextFieldDelegate? 
1

誰もmyTextfieldVariableを保持していないので...一つの方法は、慣例により、それ

1

への強い参照を保持するインスタンス変数を持っているだろう、デリゲートの参照が弱いです。それは保持サイクルを妨げる。

したがって、あなたは

myTextField.delegate = myTextFieldDelegate 

を言うとき、テキストフィールドは、デリゲートに所有参照を保持していません。

あなたのコードのインクルードがmyDelegateオブジェクトを作成する場合は、メソッド内である:

func someFunction() { 
    let myTextFieldDelegate = MyTextFieldDelegate() 
    myTextField.delegate = myTextFieldDelegate 
    scrollView.addSubview(myTextField) 
} 

が続いて変数myTextFieldDelegateは、新しく作成されたMyTextFieldDelegateオブジェクトへの強い参照を保持しています。ただし、変数myTextFieldDelegateは、関数が返されるとすぐに有効範囲外になります。

MyTextFieldDelegateオブジェクトへの強い参照がありません。したがって、割り当てが解除されます。

class MyViewController: UIViewController { 

    //myTextFieldDelegate is now an instance variable. 
    //It will hold a strong reference. 
    var myTextFieldDelegate: MyTextFieldDelegate? 

    func someFunction() { 
     myTextFieldDelegate = MyTextFieldDelegate() 
     myTextField.delegate = myTextFieldDelegate 
     scrollView.addSubview(myTextField) 
    } 
} 
関連する問題