0

ナビゲーションバーのUISegmentedControlを使用してアプリケーションのUIViewControllerを切り替えます。ただし、UIViewControlsを複数回切り替えると、ナビゲーションバーからUISegmentedControlが消えます。これは、セグメント化されたコントロールが押されるたびにビューコントロールが初期化されずに新たに割り当てられた場合にのみ発生します。つまり、私は私のアプリでビューを切り替えるたびに新しいUIViewControllerを割り当てる場合、期待された動作が観察されます(例えば、UISegmentedControlは消えません)。しかし、ユーザーがビューを切り替えたときに隠しビューの状態を保存したいので、これは実際的な解決策ではありません。UIViewControllerが常に再インスタンス化されないと、UINavigationBarのUISegmentedControlが消えます

私はhereこれが観察される簡単なプロジェクトのレポを持っています。このプロジェクトは2つのコミットで構成されています。この問題が発生した古いものと、一定の再インスタンス化によって問題が解決された新しいものです。以前約


さらなる詳細は、このリポジトリにコミット:アプリケーションのための2つのビューコントローラ(RootViewControllerとCalendarViewController)は、両方のアプリケーションの寿命のためにインスタンス化されるaccountingAppDelegateで

didFinishLaunchingWithOptionsです。

UISegmentedControlは、didFinishLaunchingWithOptionsメソッドのSegmentedControl.xibという名前のNIBファイルからロードされます。

accountingAppDelegateのtoolBarItemsメソッドは、各ビューコントローラのtoolbarItemsプロパティが設定されているビューコントローラのviewDidAppearメソッドの両方の簡易メソッドです。 UINavigationControllerは、このプロパティを参照して、the Apple docsを理解した上で、現在のビューのナビゲーションツールバーの項目を割り当てます(「ツールバーの表示」を参照)。

新しいコミットの唯一の違いは、ユーザーが1つずつ切り替えるたびにRootViewControllerとCalendarViewControllerの新しいインスタンスが作成されることです。


私の質問は、なぜ、定数の再インスタンス化が問題を解決するのですか?さらに重要なのは、UISegmentedControlが消えないようにすることができますは私のアプリケーションのビューステートを保持していますか?

+0

私はあなたのコードを正しく理解していれば、あなたが何をしているのですか? 1.あなたのappDelegateでUINavigationControllerのインスタンスを作成します。 2. RootViewControllerのインスタンスを作成します。これは、UIViewControllerのカスタムクラスです。 3. CalendarViewControllerのインスタンス、つまりUIViewControllerのカスタムクラスを作成します。 4. UINavigationControllerのrootViewControllerとしてスワップします(箇条書き1)。 それは正しいですか? – Canopus

+0

はい。これは正しいです。具体的には、UINavigationControllerの 'setViewControllers:'メソッドを使用して、UINavigationControllerのrootViewControllerプロパティを間接的に変更します。これが起こる場所を知るには、accountingappdelegateのindexDidChangeForSegmentedControlメソッドを参照してください。 – Coder

答えて

0

コメントに基づいて、私はこれが適切な方法であるとは思わない。 rootViewControllerUINavigationControllerに交換すると、基本的にリセットされます。ですから、viewControllerを再度初期化する必要があります。

  1. (例えばcvc
  2. CalendarViewControllerのインスタンスを作成RootViewController(例えばrvc
  3. のインスタンスを作成NSArrayまたはNSMutableArrayに追加します:

    私の提案は、あなたが次のことを行うということです

  4. UINavigationControllerinitWithRootViewController:のインスタンスを作成し、UIViewControllerのインスタンス(ではないまたはcvc)。
  5. 最初に表示したいものから始めます。例:

    pushViewController:RVCアニメーション:NO

  6. あなたが交換する必要があります。

    popToRootViewControllerAnimated:NO

    pushViewController:CVCアニメーション:NO

のUINavigationControllerの観点からビュー、あなたはポップしていて、ユーザーの視点からviewControllerをプッシュしています - アニメーション化されていないので、スワップしていますping!

アニメーションが必要な場合は、このようにすることはできません。 最初にUINavigationControllerの代わりにUIViewControllerを使用し、UISegmentを使用してUIToolBarを追加し、にcvcrvcのビューを追加し、必要に応じてアニメーションでスワップします。

その他の提案: このメソッド[NSArray arrayWithObject:[[CalendarViewController alloc]init]];は適切ではありません。 NSArrayにオブジェクトを渡すと、NSArrayはそのオブジェクトを所有しているので、それを保持します。それをinit/allocするのではなく、NSArrayに渡した後、リリースしなければならない。

+0

[この記事](http://redartisan.com/2010/5/26/uisegmented-control-view-switching-revisited)に基づいてこの方法を思いついたので、他の人がこれをやっていることは分かっています。また、この記事では、保守性とコードの再利用という観点から、サブビューコントローラ**の配列を囲む管理ビューコントローラに対して警告します。なぜ私の方法がうまくいかないのか、私はもっと興味があります。 UINavigationControllerを「一種のリセット」しているとはどういう意味ですか?これを拡大してもいいですか? – Coder

+0

あなたが私に与えたリンクに基づいて、これは起こります:あなたが[self.navigationController setViewControllers:theViewControllers animated:NO]と言うとき。 UINavigationControllerのviewControllerの配列を新しいviewControllersのセットに置き換えます。ここでは、この配列にはviewControllerが1つだけ含まれています。これにより、UISegmentControlを含むtitleViewを含むすべてを配置します。次の行は言う:incomingViewController.navigationItem.titleView = aSegmentedControl; これを取り消しているか、SegmentコントローラをtitleViewに追加しておくといいでしょう。 – Canopus

+0

ただし、リポジトリを詳しく見ると、incomingViewController.navigationItem.titleViewを使用してUISegmentedControlを設定していないことがわかります。これは、他のものを表示するためにナビゲーションバーが必要なためです。したがって、表示されている各View ControllerのtoolbarItemsプロパティを使用します。つまり、あなたが話すコードを使用することはできません。自分のコードがなぜ機能しないのかを理解する必要があります。incomingViewController.navigationItem.titleView = aSegmentedControlを使用しないでください。 – Coder

関連する問題