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

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

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

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

Q&A

解決済

1回答

2064閲覧

規模の大きいプロジェクトでのコードによる画面遷移の設計

taratail

総合スコア76

Swift

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

0グッド

0クリップ

投稿2015/08/23 08:44

編集2015/08/23 14:03

画面遷移の方法には通常navigationControllerによる遷移があるかと思われます。

あるプログラムを複数のモジュールに分割していて、異なるモジュール間でいかのように複数のViewControllerが存在します。

ModuleA: ViewController1
ModuleB: ViewController2, ViewController3
ModuleC: ViewController4

このとき、各ViewControllerのインスタンスを保持したまま、navigationControllerで遷移するために、プログラムをモジュール化する前までは、

Swift

1AppDelegate.swift 2 3let app = UIApplication.sharedApplication().delegate! as! AppDelegate 4 5@UIApplicationMain 6class AppDelegate: UIResponder, UIApplicationDelegate { 7 8 var window: UIWindow? 9 var navigationController: UINavigationController! 10 var someViewController = SomeViewController() 11 var otherViewController = OtherViewController() 12 var anotherViewController = AnotherViewController() 13 ... 14} 15

と、インスタンスをすべてAppDelegateに配置する方法をとっていました。しかしモジュール化したことによって、それぞれのモジュールからAppDelegateのインスタンスを確保しようとすればimportで循環参照が発生してしまいます。

こういった場合、全てのViewControllerに対して

Swift

1SomeViewController.swift in module1 2 3public class SomeViewController : UIViewController { 4 public weak var delegate: SomeViewControllerDelegate? 5 6 func aTransitionMethod() { 7 delegate?.pushViewControllerWithIdentifier("SomeViewController") 8 } 9} 10 11public protocol SomeViewControllerDelegate: class { 12 func pushViewControllerWithIdentifier(identifier: String) 13 func popViewController() 14}

といったように遷移用のdelegateを付加し、各モジュールがAppDelegateを含むモジュールを参照しないようにする方法を考えましたが、あまり良い方法に思えません。
あるいは、AppDelegateを使うことが問題なだけであって、すべての親のViewControllerを用意して、他のViewControllerのdelegateを一括で持つのが良いということでしょうか。

またこのやり方であれば、これらのViewControllerを全て参照するクラス(AppDelegateなど)で、identifierの値が実際にどのクラスを示すかswitchで分岐する必要が生じると思いますが、それは問題のない設計でしょうか。

より良い解決策はあるでしょうか。ご教示をお願いします。

追記
そもそもモジュールの分割方法として、ViewControllerがアチラコチラに散らばる設計が間違っているのでしょうか。そうであればモジュールは

Module1 = Modelのみ
Module2 = ViewControllerのみ
Module3 = カスタムViewのみ

などとして分割されるべきでしょうか。自分は元々は以下のように分離しています。

Module1 = Modelのみ
Module2 = ViewController & カスタムView の一部
Module3 = ViewController & カスタムView の一部
....

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

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

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

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

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

guest

回答1

0

ベストアンサー

画面遷移のために、navigationControllerを参照したいだけなら、UIViewControllerのnavigationControllerプロパティで参照できます。

あと、Moduleを分けるなら、それぞれのModule同士の結合度が弱くなるように設計してください。
逆にいうと、結合度の強いものはModuleとして分割できません。

ちなみに、手動でビルドスクリプトを書けば、Module同士が相互参照していてもビルドできます。

投稿2015/08/23 15:52

Stripe

総合スコア2183

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

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

taratail

2015/08/24 03:38

回答有難うございます。プロパティから参照できたのですね。 差し支えなければですが、ビルドスクリプトの例を簡単に教えてはいただけないでしょうか。
Stripe

2015/08/24 12:05

SRCDIR=$SRCROOT/$TARGET_NAME SWIFT_FILES="*.swift" SRCFILES=`ls $SRCDIR/$SWIFT_FILES` MODULEDIR=$TARGET_BUILD_DIR/$PRODUCT_MODULE_NAME.swiftmodule mkdir -p $MODULEDIR swiftc -emit-module -module-name $PRODUCT_MODULE_NAME -module-link-name $PRODUCT_MODULE_NAME $SWIFT_OPTIMIZATION_LEVEL -sdk $SDKROOT $SRCFILES -I $TARGET_BUILD_DIR -F $TARGET_BUILD_DIR -L $TARGET_BUILD_DIR -g -o $MODULEDIR/$ARCHS.swiftmodule mkdir -p $OBJECT_FILE_DIR cd $OBJECT_FILE_DIR swiftc -emit-library -emit-object -module-name $PRODUCT_MODULE_NAME $SWIFT_OPTIMIZATION_LEVEL -sdk $SDKROOT -I $TARGET_BUILD_DIR -F $TARGET_BUILD_DIR -L $TARGET_BUILD_DIR -g $SRCFILES OBJECT_FILES="*.o" OBJFILES=`ls $OBJECT_FILE_DIR/$OBJECT_FILES` libtool -static -o $TARGET_BUILD_DIR/lib$PRODUCT_MODULE_NAME.a $OBJFILES swiftmoduleファイルはC言語のヘッダーファイル相当です。 最初に相互参照している全てのModuleのswiftmoduleファイルを生成した後に、個々のModuleをコンパイルすれば、相互参照を解決できます。
taratail

2015/08/24 13:24

返信有難うございます!ビルドスクリプトもとても役立ちそうです。 swiftmoduleがそのような役割を持っていることを知りませんでした。ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.51%

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

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

質問する

関連した質問