前提・実現したいこと
こんばんは。いつもお世話になってます。
Stoty board無しで開発をしています。ナビゲーションバーのOkボタンをタップした時にテキストフィールドの文字が空だったら、アラートを表示する。空じゃなかったら、特に何も起きない。という処理の実装をしたいのですが上手くいきません。
下記ソースコードの説明
ViewController.swfit と View.swift がやり取りをするために ViewController.swift でプロトコルを作っています。
Okボタンがタップされた時に、プロトコルのメソッドを実行して返ってきた値が true か false かでアラートを出すか出さないか決めています。
現状と推測
プロトコルのメソッドの返り値が true か false 以前に、 nil になってしまいます。 View.swift に移譲してあるプロトコルのメソッドが、ログを見る限り起動( print(return fasle), print(return true)の箇所 )していないので、 ViewContoller.swift の delegate? の部分でオプショナルチェイニング?がかかり、それ以降の .confirmTextFeild() が実行されず nil になってしまっているのだと僕は考えているのですが、解決できません。
プロトコルのメソッドに返り値を設定したのは今回が初めてですが、今までの返り値なしで自分で作成してきたプロトコルは何も問題無く動いていたので原因が分からず悩んでいます。
シュミレータとログ画面
該当のソースコード
ViewController
1import UIKit 2 3protocol ViewControllerDelegate { 4 func confirmTextFeild() -> Bool 5} 6 7class ViewController: UIViewController { 8 9 var subView: UIView! 10 var delegate: ViewControllerDelegate? 11 12 override func viewDidLoad() { 13 super.viewDidLoad() 14 15 view.backgroundColor = .white 16 configureNavItem() 17 configureSubView() 18 } 19 20 override func viewDidLayoutSubviews() { 21 subView.frame = CGRect(x: view.bounds.origin.x, y: view.bounds.origin.y, width: view.bounds.width, height: view.bounds.height) 22 } 23 24 func configureSubView() { 25 subView = View() 26 view.addSubview(subView) 27 } 28 29 func configureNavItem() { 30 31 navigationItem.rightBarButtonItem = UIBarButtonItem(title: "OK", style: .plain, target: self, action: #selector(tappedOk)) 32 33 } 34 35 @objc func tappedOk() { 36 37 let flag = delegate?.confirmTextFeild() 38 39 if flag == nil { 40 print("nil") 41 return 42 } 43 44 if !flag! { 45 print("No") 46 let alertController = UIAlertController(title: "メッセージ", message: "文字が記入されていません", preferredStyle: .alert) 47 alertController.addAction(UIAlertAction(title: "ok", style: .default, handler: nil)) 48 present(alertController, animated: true, completion: nil) 49 } else { 50 print("ok") 51 } 52 } 53 54}
View
1import UIKit 2 3class View: UIView { 4 5 var textField: UITextField! 6 var viewController: UIViewController! 7 8 override init(frame: CGRect) { 9 super.init(frame: frame) 10 11 configureTextField() 12 configureViewControllerDelegate() 13 } 14 15 func configureTextField() { 16 textField = UITextField() 17 textField.backgroundColor = .darkGray 18 textField.textColor = .white 19 addSubview(textField) 20 } 21 22 func configureViewControllerDelegate() { 23 let localViewController = ViewController() 24 localViewController.delegate = self 25 viewController = localViewController 26 } 27 28 required init?(coder: NSCoder) { 29 fatalError("init(coder:) has not been implemented") 30 } 31 32 override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { 33 self.endEditing(true) 34 } 35 36 override func layoutSubviews() { 37 textField.frame = CGRect(x: Double(self.center.x / 2), y: Double(self.center.y), width: 200, height: 40) 38 } 39 40} 41 42extension View: ViewControllerDelegate{ 43 44 func confirmTextFeild() -> Bool { 45 if textField.text == "" { 46 print("return false") 47 return false 48 } else { 49 print("return true") 50 return true 51 } 52 } 53 54} 55 56extension View: UITextFieldDelegate { 57 58 func textFieldShouldReturn(_ textField: UITextField) -> Bool { 59 textField.resignFirstResponder() 60 } 61 62}
試したこと
View.swiftでViewController.swiftをインスタンス化して、delegate = self にする場所が悪いのかと思い、他の箇所に変えて実行したのですが、上手くいきませんでした。
引き続き自分でも原因を探りますが、どなたか原因が分かる方がいましたらご回答お願いします。
補足情報
xcodeバージョン11.3.1
回答1件
あなたの回答
tips
プレビュー