web-dev-qa-db-ja.com

ストーリーボードXcode 6の適応セグエ。Pushは非推奨ですか?

Xcode 6インターフェイスビルダーには、デフォルトで「サイズクラスを使用」という新しいチェックボックスがあります。ビューを適応的にします。 enter image description here

ストーリーボードで2つのビュー間でセグエを作成しようとすると、新しいオプションがあります。 enter image description here

代わりに古い:

enter image description here

これで、「プッシュ」と「モーダル」の代わりに「ショー」と「モーダルモードで」ができました。古いオプションは非推奨としてマークされています。セグエ設定では「show(例:Push)」と呼ばれるため、「show」オプションを選択しました

enter image description here

しかし、それはプッシュを行いません。セグエアニメーションは下からスライド(モーダル)のように見え、ナビゲーションバーは消えます。

質問:プッシュのように「ショー」を機能させるにはどうすればよいですか?代わりに「プッシュ(非推奨)」を使用する必要がありますか?新しいタイプのセグエに関する情報はどこで入手できますか? iOS8開発者ライブラリで私が見つけた唯一のものは ストーリーボードはユーザーインターフェイスの設計に役立ちます ですが、「show」セグエに関する情報はありません。

更新

私は新しいプロジェクトを作成しようとしましたが、「show」は本当に「Push」のように機能します。私のプロジェクトの問題は、Navigation Controllerをこのようなコードで再利用するためだと思いますが、それを修正する方法がわかりません。

if ( [segue isKindOfClass: [SWRevealViewControllerSegue class]] ) {
    SWRevealViewControllerSegue *swSegue = (SWRevealViewControllerSegue*) segue;

    swSegue.performBlock = ^(SWRevealViewControllerSegue* rvc_segue, UIViewController* svc, UIViewController* dvc) {

        UINavigationController* navController = (UINavigationController*)self.revealViewController.frontViewController;
        [navController setViewControllers: @[dvc] animated: NO ];
        [self.revealViewController setFrontViewPosition: FrontViewPositionLeft animated: YES];
    };

}

その後、MainViewControllerの後にNewViewControllerをプッシュしようとします enter image description here

更新2:

私はiOS 7、iOS 7.1の問題だけのようです。

118
John Kakon

はい、「プッシュ」の代わりに「表示」を使用します

プッシュのように「ショー」を機能させるにはどうすればよいですか?可能ですか、代わりに「Push(depricated)」を使用する必要がありますか?

そうすべき;それは私のために。 Xcode 6ベータ2を使用しており、テストにはシングルビューテンプレートを使用しました(IB「VC_A」の既製のビューコントローラーを呼び出します)。次に、別のView Controller(「VC_B」)を追加しました。次に、VC_Aにボタンを追加して、VC_BとVC_BからVC_Aに戻る別のボタンを表示します。ストーリーボードの最初のView ControllerとしてNavigation Controllerを追加し、VC_AをrootViewControllerにすると、「Push」と「show」の両方に同じ効果があります。最初のNavigation Controllerがなく、「show」を使用すると、VC_Bが下から上にスライドするという説明が表示されます。 「プッシュ」しようとすると、プッシュを行うためにナビゲーションコントローラーが必要になるため、クラッシュします。そのため、「show」は、Navigation Controllerが提供されている場合はPushを実行し、Navigation Controllerが存在しない場合はモーダル遷移スタイルでプレゼンを実行するように見えます。

新しいタイプのセグエに関する情報はどこで入手できますか?

そこで、「Interface Builderの新機能」セッションで情報を見つけました こちら 。スライドを見ると、1つのスライド(41)が変更について言及していることがわかります。そのセッションビデオを視聴するときは、38:00にスキップして、アダプティブセグエについて話し始めることができます。たとえば、「show」アダプティブセグエは、新しいView Controllerのプレゼンテーション方法を決定する際にコンテキストを考慮に入れることを説明しています。

94
Spencer Hall

既に受け入れられた答えがありますが、私はもう少し情報を与えたいと思いました。おそらく以前は入手できなかった情報です。

前に述べたように、「プッシュ」および「モーダル」セグエは廃止され、それぞれ「ショー」および「現在モーダル」に置き換えられました。 Appleのドキュメントによると、新しいセグエはサイズクラスに適応するセグエにさらに分割されています。古いバージョンは、iOS 8よりも古いバージョンのiOSをサポートするためにのみ使用してください。

次のリンクのドキュメントでは、そのことと、使用可能なすべてのセグエ(古いものと新しいもの)の説明を説明しています。

ストーリーボードのシーン間にセグエを追加する

URLが将来変更される場合、これは新しいセグエごとに与えられる説明です:

ショー

画面のコンテンツに応じて、詳細またはマスター領域にコンテンツを表示します。アプリにマスタービューと詳細ビューが表示されている場合、コンテンツは詳細領域にプッシュされます。アプリがマスターまたは詳細のみを表示している場合、コンテンツは現在のView Controllerスタックの上にプッシュされます。

詳細を表示

詳細領域でコンテンツを提示します。アプリがマスタービューと詳細ビューを表示している場合、新しいコンテンツが現在の詳細を置き換えます。アプリがマスターまたは詳細のみを表示している場合、コンテンツは現在のView Controllerスタックの上部を置き換えます。

モーダルプレゼント

コンテンツをモーダルで提示します。プレゼンテーションスタイル(UIModalPresentationStyle)と遷移スタイル(UIModalTransitionStyle)を選択するオプションがあります。

ポップオーバーとしてプレゼント

既存のビューに固定されたポップオーバーとしてコンテンツを提示します。ポップオーバービューの1つのエッジに表示される矢印の可能な方向を指定するオプションがあります(UIPopoverArrowDirection)。アンカービューを指定するオプションもあります。

32
alondono

tldr; UIView/UIControlからターゲットView Controllerにドラッグして、正しくプッシュされていないセグエを削除し、ストーリーボードで再作成します。

他の回答には何も問題はありませんが、これは何が起こっているのか、それが起こっていることをどのように確認できるのか、そして将来どのように問題を軽減するのかを説明しています。

背景

私の場合、最初のビューコントローラーとしてUINavigationControllerが既に(コンテンツUIViewControllerをルートとして)持っていたにもかかわらず、私のショーセグはどれも動作していませんでした。

ショーセグエが中断する理由と方法

ストーリーボードのソースxml内でセグエに関連付けられたアクションがある場合、ショーのセグエは壊れます。これを引き起こす典型的なシナリオは、以前にコードで呼び出された手動セグエからセグエを再定義した場合です。これにより、ストーリーボードxmlに次のビットが残ります。

<connections>
    <segue destination="85t-Z1-hxf" kind="show" identifier="ToOptions" action="showDetailViewController:sender:" id="gdZ-IX-KcN">
</connections>

Nota BeneストーリーボードをXMLとして表示するには;ストーリーボードファイルを右クリックし、[開く]> [ソースコード]を選択します。元に戻すには、[開く]> [インターフェイスビルダー-ストーリーボード]を使用します

ストーリーボードからセグエを使用するときにカスタムアクションに対応するには、prepareForSegueをタップして、宛先View Controllerをインターセプトし、その場所からメソッドを呼び出すだけです。いずれにせよ、この小さなバグの副作用(バグは、セグエを再定義するとxmlで適切に設定されないという事実です。つまり、セグエをUIViewから動作するものに変更した後でもアクションが残ります(またはUIControl)からターゲットView Controllerへ)。

残念ながら、最も直接的な解決策は失敗します。そのため、ストーリーボード内からアクションのxml属性を削除するだけでNOTが問題を修正します。代わりに、ストーリーボードでセグエを単に削除して再作成する必要があります。

再作成すると、ストーリーボードxmlには特定のセグエに関連付けられたアクションがなくなり、ショーはプッシュとして実行されます。

正しいセグエのXmlのサンプル

  <connections>
    <segue destination="RbV-Au-WV9" kind="show" identifier="ToOptions" id="5dm-os-bcS"/>
  </connections>

軽減

再発を防ぐには、prepareForSegueを使用して宛先View Controllerに基づいて必要なアクションを追加することにより、可能であれば、手動以外のストーリーボードセグエに固執する必要があります。または、組み合わせて一致させる必要がある場合は、ショーのセグエにストーリーボードxmlでアクションが添付されていないことを確認する予防策を講じてください。古いプロジェクトを扱っている場合は、いくつかの問題を発見したため、ストーリーボードのソースコードに特別な注意を払う必要があります。

23
Tommie C.

Scott Robertsonがここにコメントした のように、これはiOS 7のバグのように見えます。

IOS 8では、実行時に遷移が推測されます(正しい動作)が、iOS 7では、設計時に遷移が推測されます(バグのある動作)。

最も簡単な回避策は、未使用のNavigation Controllerをストーリーボードに追加してリンクし、問題のView ControllerがこのNavigation Controllerの一部になるようにすることです。 Navigation Controllerを実際にインスタンス化する必要はありません。NavigationControllerに組み込まれていることを知るには、バグのあるView Controllerが必要です。

注:ナビゲーションバーのシミュレーションは、これらの目的には不十分です。実際には、PushスタックにNavigation Controllerが必要です。

バグを再現するには:

  1. サイズクラスを使用する新しいストーリーボードを作成します。
  2. 2つのView Controllerを作成します(Navigation Controllerなし)。
  3. たとえば、ボタンにリンクされたShow(例:Push)セグエを介して、最初のView Controllerに2番目のView Controllerを表示させます。
  4. コードでは、最初のView Controllerを表示しますが、initWithRootViewController:メソッドを介してNavigation Controllerに埋め込みます。
  5. IOS 7でアプリを実行します。
  6. プッシュを実行するボタンをタップします。
  7. IOS 7ではプッシュの代わりにモーダルトランジションを取得します。iOS8では、正しいプッシュ動作を取得します。

enter image description here

バグを修正するには:

  1. ストーリーボードにNavigation Controllerを追加し、最初のView ControllerをルートView Controllerに設定します。 (注:2番目をルートView Controllerとして追加しても、このバグは修正されません。)
  2. ジャンク識別子を付けて、Navigation Controllerにアクセスできないという警告を抑制し、回避策としてのみ存在することを自分自身に文書化します。 (例:workaround for show segues in iOS 7)。

enter image description here

2番目の画像でNavigation Controllerが追加された方法、および矢印が入っていないことに注意してください(つまり、View Controller識別子を使用する以外にインスタンス化する方法はありません)。

20
Senseful

私はこれに遅れていることを知っていますが、私が学んだことを共有したかったです。これは実際にはバグであり、今日でも存在しています(2014-12-18)。

これについての記事を書きました here

簡単に再現できます。 Showセグエを呼び出す前にViewControllerをプログラムでスタックにプッシュしない限り、iOS8ではiOS7.xでも問題なく動作します。

ストーリーボード接続を使用してスタックにプッシュするだけで機能します。しかし、どうやらコード経由でプッシュすると、プッシュされたnavigationControllerUIViewControllerプロパティはnilになり、Showを呼び出すと、スタックを制御するナビゲーションがないため、モーダルと見なされます。

これまでの唯一の回避策は、コード経由のプッシュ(実行不可能)または現在非推奨のPushを使用することです。

レーダーを提出しました(記事へのリンク)。 Appleがこの問題を修正することを期待して、重複をファイルしてください。

13
esttorhe

Xcode 7とiOS 7.1.2のセグエにも同じ問題がありました。セグエの表示(iOS 8の新機能)は、iOS 7のモーダルセグエのように動作し、次の場合にView ControllerをNavigation Controllerスタックにプッシュすることを許可しませんストーリーボードでXcodeを使用してセグエタイプを定義します。 View Controllerがスタックにプッシュされず、ポップできないため、self.navigationControllerがnilを返すのはそのためです。

アプリがiOS 7で動作する必要があるときに、XcodeでAppleがこのケースの通知を追加しなかった理由がわかりません。Pushメソッドは廃止されたと言いますが、 iOS 7ではShowは正しく機能しません。

問題を解決するために何をしましたか:

.hでMYShowSegueクラスを作成しました

#import <UIKit/UIKit.h>

@interface MYShowSegue : UIStoryboardSegue

@end

そして、1つのperformメソッドを持つ.mファイル:

#import "MYShowSegue.h"

@implementation MYShowSegue

- (void) perform {

    if ([[[self sourceViewController] navigationController] respondsToSelector:@selector(showViewController:sender:)]) {

        id sender = nil;
        [[[self sourceViewController] navigationController] showViewController:[self destinationViewController] sender:sender];
    }else{

        [[[self sourceViewController] navigationController] pushViewController:[self destinationViewController] animated:YES];
    }
}

@end

ストーリーボードの各セグエにCustomタイプを設定し、そのための新しいクラスを選択する必要があるよりも、私の場合はMYShowSegueでした。

カスタムセグエの例

このソリューションは、iOS 7アプリを完全にサポートするのに役立ちます。アプリは、pushViewControllerメソッドを使用して、ビューをプッシュしたり、iOS 8,9などに対応します。 。セグエは新しい(iOS 8)メソッドshowViewControllerで動作します

ストーリーボードのすべてのセグエで同じことを忘れないでください。

2
Igor Tikhonov

これはまだiOS 10.xで発生しています

セグエの削除と復元は、私にとっては何も解決しませんでした。

問題:必要な機能は7つのセグエで、「プッシュ」(実際にはショーの詳細)としてのみ動作しますが、実際には、最初に追加したセグエのみがプッシュされ、その他はすべてモーダルに動作します。これは、Interface Builderが各セグエを同じように記述しているにもかかわらずです。

解決策:アクションを持たない6つのセグエにアクションを追加する必要がありました。

オリジナルストーリーボードXML

<connections>
  <segue destination="tIr-4a-WfZ" kind="showDetail" identifier="A" action="showViewController:sender:" id="8yd-Ne-7KA"/>
  <segue destination="4mB-YE-5dM" kind="showDetail" identifier="B" id="Uod-JC-786"/>
  <segue destination="Qh5-bJ-KcE" kind="showDetail" identifier="C" id="3PW-nV-hWl"/>
  <segue destination="EI6-f4-QBB" kind="showDetail" identifier="D" id="WUK-ju-KDm"/>
  <segue destination="nTz-N4-fpW" kind="showDetail" identifier="E" id="Id6-bW-Huc"/>
  <segue destination="JEp-CH-6dW" kind="showDetail" identifier="F" id="G0L-XW-7f4"/>
  <segue destination="AET-S1-O6h" kind="showDetail" identifier="G" id="3NK-93-wTy"/>
</connections>

showViewController:senderを追加してこれを変更しました

<connections>
  <segue destination="tIr-4a-WfZ" kind="showDetail" identifier="A" action="showViewController:sender:" id="8yd-Ne-7KA"/>
  <segue destination="4mB-YE-5dM" kind="showDetail" identifier="B" action="showViewController:sender:" id="Uod-JC-786"/>
  <segue destination="Qh5-bJ-KcE" kind="showDetail" identifier="C" action="showViewController:sender:" id="3PW-nV-hWl"/>
  <segue destination="EI6-f4-QBB" kind="showDetail" identifier="D" action="showViewController:sender:" id="WUK-ju-KDm"/>
  <segue destination="nTz-N4-fpW" kind="showDetail" identifier="E" action="showViewController:sender:" id="Id6-bW-Huc"/>
  <segue destination="JEp-CH-6dW" kind="showDetail" identifier="F" action="showViewController:sender:" id="G0L-XW-7f4"/>
  <segue destination="AET-S1-O6h" kind="showDetail" identifier="G" action="showViewController:sender:" id="3NK-93-wTy"/>
</connections>
1
Damo