質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

Q&A

解決済

1回答

528閲覧

Swift5 xib + CustomView の dependancy injection

mogiruri

総合スコア37

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

0グッド

0クリップ

投稿2019/07/08 05:29

編集2019/07/08 05:33

こんにちは。

dependancy injectionについて理解しようと試みています。

Storyboard を使用したインスタンス化を用いて行うDIはなんとかできたのですが、
UITableViewCell + cellのxibを使用してfunc inject()を呼ぶところでpresenterがnilとなってしまいます。

xibの扱いとDIにはまだ不慣れですので、お助けいただけると幸いです。

そもそもこれがDIになっているか不安なのですが。。。

class AppDelegate内で注入しています。

swift

1class AppDelegate: UIResponder, UIApplicationDelegate { 2 3 var window: UIWindow? 4 5 func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 6 7     // 以下、presenterを、各VCに設置したinject()にて注入 8 let mainTabVC = UIStoryboard(name: "MainTab", bundle: nil).instantiateInitialViewController() as! MainTabViewController 9 let userDefault = UserDefault() 10 let presenter = MainTabPresenter(view: mainTabVC, udManager: userDefault) 11 mainTabVC.inject(presenter: presenter, userDefaultManager: userDefault) 12 13 let addTabVC = UIStoryboard(name: "AddTab", bundle: nil).instantiateInitialViewController() as! AddTabViewController 14 let alertHandller = AlertHandller() 15 let addPresenter = AddTabPresenter(view: addTabVC, mainView: mainTabVC, alertHandller: alertHandller) 16 addTabVC.inject(presenter: addPresenter) 17 18 let settingTabVC = UIStoryboard(name: "SettingTab", bundle: nil).instantiateInitialViewController() as! SettingTabViewController 19 let settingPresenter = SettingTabPresenter(view: settingTabVC) 20 settingTabVC.inject(presenter: settingPresenter, alertHandller: alertHandller) 21 22 let vcs = [mainTabVC, addTabVC, settingTabVC] 23 24 let mainTabBar = UIStoryboard(name: "MainView", bundle: nil).instantiateInitialViewController() as! MainTabBarController 25 mainTabBar.setViewControllers(vcs, animated: false) 26 27     // ここまでは問題なし。無事VC内にてpresenterにアクセス可能 28 29 30 // CustomTableViewCellにはxibを使用していて、これだとView内で呼ぶpresenterがnilになる 31     // ListCell.xib xibファイル 32 // ListCell.swift CustomView 33 let listCell = UINib(nibName: "ListCell", bundle: nil).instantiate(withOwner: nil, options: nil).first as! ListCell 34 35 let cellPresenter = ListCellPresenter(view: mainTabVC) 36 listCell.inject(presenter: cellPresenter) 37 38 window = UIWindow(frame: UIScreen.main.bounds) 39 window?.rootViewController = mainTabBar 40 window?.makeKeyAndVisible() 41 42 return true 43 } 44} 45 46// customTableViewCell 47class ListCell: UITableViewCell { 48 49 private let shared = Sharing.shared 50 private var presenter: ListCellPresenter! 51 52 func inject(presenter: ListCellPresenter) { 53 self.presenter = presenter 54 } 55 56 override func awakeFromNib() { 57 super.awakeFromNib() 58 } 59 60 override func setSelected(_ selected: Bool, animated: Bool) { 61 super.setSelected(selected, animated: animated) 62 63 // Configure the view for the selected state 64 } 65 66 @IBAction func favButtonTapped(_ sender: Any) { 67 let row = self.tag 68 presenter.countFavIcon(rowAt: row) //このpresenterがnil 69 } 70} 71 72//cellのpresenter 73 74protocol ListCellPresenterInput { 75 func countFavIcon(rowAt row: Int) 76} 77 78protocol ListCellPresenterOutput: AnyObject { 79 func update() 80} 81 82final class ListCellPresenter: ListCellPresenterInput { 83 84 private let shared = Sharing.shared 85 private weak var view: ListCellPresenterOutput! 86 87 init(view: ListCellPresenterOutput) { 88 self.view = view 89 } 90 91 func countFavIcon(rowAt row: Int) { 92 print("called") 93 view.update() 94 } 95} 96

withOwner: nil これを withOwner: ListCell.self にもしてみましたがダメでした。

よろしくお願いします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

質問がいまいち理解できていませんので、的外れならすいません。

Swift

1let listCell = UINib(nibName: "ListCell", bundle: nil).instantiate(withOwner: nil, options: nil).first as! ListCell

AppDelegateのdidFinishLaunchingWithOptionsメソッド内で生成した上記listCellはどこにも使用されず、そのまま破棄されています。

仮に、別ソースコードの func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell でListCellを生成し、injectしていないなら、そのListCellのpresenterはnilです。
AppDelegateのlistCellとは別のインスタンスですし、presenterはstaticでもありません。
Sharing.sharedがシングルトンの様なものを想定していそうですが、それとも紐付いていません。

投稿2019/07/08 12:46

dsuzuki

総合スコア1682

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

mogiruri

2019/07/08 13:33

コメントありがとうございます。 AppDelegateのdidFinishLaunchingWithOptionsメソッド内で生成した上記listCellはどこにも使用されず、そのまま破棄されています。 そうなのですね。なんとなくわかった気がするのですが、こちらには記載していませんが、cellはcellForRowAtにてdequeueReusableCellをしようし、要素をCustomCell内にあるconfigureにて作成しています。 ということは、ここのインスタンスを使用して cell.inject()のように呼べば良いということでしょうか? おっしゃる通り、Sharing.sharedはシングルトンで、presenter内の他の処理でしようすることを想定しています。
dsuzuki

2019/07/10 03:21

> ここのインスタンスを使用して cell.inject()のように呼べば良いということでしょうか? cellForRowAt内でpresenterが生成できるならそれで良いと思います。 ただし、ここでMainViewをstoryboardから生成しても、画面に表示しているMainViewとは別インスタンスということに気をつけてください。 画面表示が変わっていないならwindow?.rootViewControllerから取得できるかもしれませんが。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問