2016年11月22日火曜日

UIButtonに渡すselfはinit後に渡そうね


最近、Androidを離れてSwiftでiOSアプリを作成していますが、次の点にはまったのでメモ 

やりたいこと

  •  イベントに応じてNavigationBarに動的にボタンを追加したり消したりする 


失敗した例

  • UIBarButtonItemのインスタンスを静的メンバとして保持しておく 
  • イベントに応じて保持しているインスタンスをセットしたりアンセットする 
class MyViewController: UIViewController {
    var rightNavEditButtonItem = UIBarButtonItem(barButtonSystemItem: .edit, target: self, action: #selector(MyViewController.test))
    
    func test() {
        print("hogehoge")
    }

    func occurSomeEvent(_ calendar: FSCalendar, didSelect date: Date) {
        self.navigationItem.setRightBarButtonItems([rightNavEditButtonItem!], animated: true)
    }
}

 これだと、UIBarButtonItemをnewしたタイミングで引数に渡しているselfが決まっていない(インスタンス化されていない)ため
コード的にエラーはなくともselectorで指定したメソッドが呼ばれない

 正しい例

  • UIBarButtonItemのインスタンスをインスタンスメンバとして保持しておく
  •  viewDidLoadなどselfが決まっている状態でUIBarButtonItemをnewする
  •  イベントに応じて保持しているインスタンスをセットしたりアンセットする
class MyViewController: UIViewController {
    var rightNavEditButtonItem : UIBarButtonItem?
    
    override func viewDidLoad() {
        rightNavEditButtonItem = UIBarButtonItem(barButtonSystemItem: .edit, target: self, action: #selector(MyViewController.test))
    }
    
    func test() {
        print("hogehoge")
    }

    func occurSomeEvent(_ calendar: FSCalendar, didSelect date: Date) {
        self.navigationItem.setRightBarButtonItems([rightNavEditButtonItem!], animated: true)
    }
}