web-dev-qa-db-ja.com

プログラムによるセグエの作成

私は私のすべてのUIViewControllerがいくつかの共通の操作を再利用するために拡張する共通のUIViewsControllersを持っています。

他のすべてのUIViewControllerが継承するように、この "Common" UIViewControllersにセグエを設定したいと思います。

私はこれをプログラムでどのように行うのかを理解しようとしています。

また、ストーリーボードに入らずに手動ですべてのsegueUIViewControllersを設定する方法も問題になる可能性があります。

200
Tiago Veloso

定義上、セグエはストーリーボードとは無関係に存在することはできません。クラスの名前の中にさえあります:UIStoryboardSegue。あなたはプログラム的にセグエを作成しません - それはあなたのためにそれらを作成するストーリーボードランタイムです。通常はView ControllerのコードでperformSegueWithIdentifier:を呼び出すことができますが、これは参照するストーリーボードにセグエがすでに設定されていることに依存しています。

私があなたが求めているのは、新しいView Controllerに移行し、すべての派生クラスに継承される、共通のView Controller(基本クラス)でメソッドを作成する方法です。これを行うには、基本クラスのView Controllerに次のようなメソッドを作成します。

- (IBAction)pushMyNewViewController
{
    MyNewViewController *myNewVC = [[MyNewViewController alloc] init];

    // do any setup you need for myNewVC

    [self presentModalViewController:myNewVC animated:YES];
}

次に、派生クラスで、適切なボタンがクリックされたとき、またはテーブル行が選択されたときなどに、そのメソッドを呼び出します。

165
jonkroll

私は私がもう一つの可能​​性を加えるだろうと思った。できることの1つは、アクションに関連付けられていないセグエを使用してストーリーボード内の2つのシーンを接続してから、View Controller内でプログラム的にそのセグエをトリガーすることです。これを行う方法は、あなたがストーリーボードシーンの一番下にあるファイルの所有者アイコンであるセグエイニングシーンからドラッグし、目的のシーンに右ドラッグする必要があるということです。説明を手助けするために画像を投げます。

enter image description here

「Manual Segue」のポップアップが表示されます。私はタイプとしてプッシュを選んだ。小さな正方形をタップして、あなたが属性インスペクタにいることを確認してください。それをコードで参照するために使用する識別子を付けます。

enter image description here

さて、次にプログラム的なバーボタンアイテムを使ってセグメンテーションするつもりです。 viewDidLoadまたは他の場所で、次のコードを使用してナビゲーションバーにボタン項目を作成します。

UIBarButtonItem *buttonizeButton = [[UIBarButtonItem alloc] initWithTitle:@"Buttonize"
                                                                    style:UIBarButtonItemStyleDone
                                                                   target:self
                                                                   action:@selector(buttonizeButtonTap:)];
self.navigationItem.rightBarButtonItems = @[buttonizeButton];

わかりました、セレクタがbuttonizeButtonTap:です。それで、そのボタンのvoidメソッドを書き、そのメソッド内であなたはこのようにセグエを呼び出すでしょう:

-(void)buttonizeButtonTap:(id)sender{
    [self performSegueWithIdentifier:@"Associate" sender:sender];
    }

PrepareForSegueが呼び出されたときに送信者パラメータがボタンを識別するために必要です。 prepareForSegueは、シーンをインスタンス化し、その作業を実行するために必要な値が何であれ、それを渡すフレームワークメソッドです。私の方法は次のようになります。

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    if ([[segue identifier] isEqualToString:@"Associate"])
    {
        TranslationQuizAssociateVC *translationQuizAssociateVC = [segue destinationViewController];
        translationQuizAssociateVC.nodeID = self.nodeID; //--pass nodeID from ViewNodeViewController
        translationQuizAssociateVC.contentID = self.contentID;
        translationQuizAssociateVC.index = self.index;
        translationQuizAssociateVC.content = self.content;
    }
}

さて、それをテストしただけでうまくいきます。お役に立てば幸いです。

343
smileBot

このコードを使用して、私のカスタムセグエサブクラスをインスタンス化し、それをプログラムで実行しました。うまくいくようです。これで何か問題がありますか?他のすべての答えを読むことはできません。

UIViewController *toViewController = [self.storyboard instantiateViewControllerWithIdentifier:@"OtherViewControllerId"];
MyCustomSegue *segue = [[MyCustomSegue alloc] initWithIdentifier:@"" source:self destination:toViewController];
[self prepareForSegue:segue sender:sender];
[segue perform];
80

これは答えられて受け入れられていると思いますが、もう少し詳しく説明します。

最初の画面としてログインビューを表示し、次にログインが正しい場合はアプリケーションにセグメンテーションしたいという問題を解決するために私がしたこと。私はログインビューコントローラからルートビューコントローラへのセグエを作成し、それに "myidentifier"のような識別子を与えました。

それからすべてのログインコードをチェックした後にログインが正しかったなら私は電話をかけます

[self performSegueWithIdentifier: @"myidentifier" sender: self];

私の最大の誤解は私がボタンにセグエを入れようとしたこと、そしてそれが発見されたらセグエを中断させることのようなものでした。

45
qrikko

あなたのコードをあなたが使っているUIStoryboardにリンクしなければなりません。必ずUIStoryboardYourViewControllerに移動し、その周囲の境界線をクリックしてから、そのidentifierフィールドをコード内で呼び出すNSStringに設定します。

UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" 
                                                     bundle:nil];
YourViewController *yourViewController = 
 (YourViewController *)
  [storyboard instantiateViewControllerWithIdentifier:@"yourViewControllerID"];
[self.navigationController pushViewController:yourViewController animated:YES];
32
Jeff Grimes

ストーリーボードにあるコントローラー用。

jhilgert00これはあなたが探していたものですか?

-(IBAction)nav_goHome:(id)sender {
UIViewController *myController = [self.storyboard instantiateViewControllerWithIdentifier:@"HomeController"];
[self.navigationController pushViewController: myController animated:YES];

}

または...

[self performSegueWithIdentifier:@"loginMainSegue" sender:self];
16
user1723341

ストーリーボードセグはストーリーボードの外側に作成することはできません。欠点があるにもかかわらず、あなたはそれを配線する必要があるでしょう。

IStoryboardSegue Reference は明確に述べています:

あなたは直接セグエオブジェクトを作成しません。代わりに、ストーリーボードランタイムは、2つのView Controller間でセグエを実行する必要があるときにそれらを作成します。必要に応じて、UIViewControllerのperformSegueWithIdentifier:sender:メソッドを使用してプログラムでセグエを起動することもできます。プログラムで追加されたため、Interface Builderでは使用できないソースからセグエを開始することができます。

presentModalViewController:またはpushViewController:animated:の呼び出しを使用してセグエを使用してView Controllerを表示するようにストーリーボードにプログラムで指示することはできますが、ストーリーボードのインスタンスが必要になります。

UIStoryboardsクラスメソッドを呼び出して、メインバンドルにbundle nilの名前付きストーリーボードを取得できます。

storyboardWithName:bundle:

uIStoryBoardSegueを作成することもサブクラス化することもできます。サブクラス化は、主にカスタムのトランジションアニメーションを作成するために使用されます。

storyBoardを紹介するwwdc 2011のビデオを見ることができます。 YouTubeでも利用可能です。

http://developer.Apple.com/library/ios/#documentation/UIKit /参照/ UIStoryboardSegue_Class /参照/参照.html#//Apple_ref/occ/cl/UIStoryboardSegue

3
Jogi Thakur

説明を加えたいのですが….

よくある誤解、実は私がしばらく前から持っていたことですが、ストーリーボードセグエはprepareForSegue:sender:メソッドによって引き起こされるということです。そうではない。そのビューコントローラからprepareForSegue:sender:メソッドを実装したかどうかにかかわらず、ストーリーボードセグエが実行されます。

私はPaul Hegartyの優秀な人物からこれを学びました iTunesUの講義 。残念ながら私の謝罪はどの講義を思い出すことができません。

ストーリーボード内の2つのView Controller間でセグエを接続しても、prepareForSegue:sender:メソッドを実装しない場合でも、セグエはターゲットのView Controllerにセグメートされます。しかし、それは準備されていないそのビューコントローラに分かれます。

お役に立てれば。

3
andrewbuilder

まず、ストーリーボードに2つの異なるビューがあり、ある画面から別の画面に移動したいとします。したがって、次の手順に従います。

1)。アイデンティティインスペクタでクラスファイルとストーリーボードIDを使用してすべてのビューを定義します。

2)。最初のビューに必ずナビゲーションコントローラを追加してください。ストーリーボードでそれを選択してから、エディタ>埋め込み>ナビゲーションコントローラ

3)。あなたの最初のクラスで、 "secondClass.h"をインポートしてください。

#import "ViewController.h
#import "secondController.h"

4)。セグエを実行する必要があるIBActionにこのコマンドを追加します。

secondController *next=[self.storyboard instantiateViewControllerWithIdentifier:@"second"];
[self.navigationController pushViewController:next animated:YES];

5)。 @"second"はセカンドビューコントローラクラス、ストーリーボードIDです。

2
Sanket Chauhan

私はUIStoryboardのセグエスをリバースエンジニアリングしてオープンソース(再)実装しました。 https://github.com/acoomans/Segway

そのライブラリを使用すると、プログラムで(ストーリーボードなしで)セグエを定義できます。

それが役立つかもしれないことを願っています。

1
acoomans

これがCreating a segue programmaticallyのコードサンプルです。

class ViewController: UIViewController {
    ...
    // 1. Define the Segue
    private var commonSegue: UIStoryboardSegue!
    ...
    override func viewDidLoad() {
        ...
        // 2. Initialize the Segue
        self.commonSegue = UIStoryboardSegue(identifier: "CommonSegue", source: ..., destination: ...) {
            self.commonSegue.source.showDetailViewController(self.commonSegue.destination, sender: self)
        }
        ...
    }
    ...
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        // 4. Prepare to perform the Segue
        if self.commonSegue == segue {
            ...
        }
        ...
    }
    ...
    func actionFunction() {
        // 3. Perform the Segue
        self.prepare(for: self.commonSegue, sender: self)
        self.commonSegue.perform()
    }
    ...
}
0
jqgsninimo

実際にはいくつかの問題があります。

まず、あなたが私たちのためにアップロードしたプロジェクトでは、segueは "segue1"という識別子を持っていません。

識別子なし

まだ行っていない場合は、その識別子を入力してください。

次に、Table ViewからTable Viewに移行するときに、initWithNibNameを呼び出してView Controllerを作成します。あなたは本当にinstantiateViewControllerWithIdentifierを使いたいのです。

0
jaydip