[VS-Mac]VisualStudio for Mac でSegue

# VisualStudio for MacのSegueサンプルプログラム(Mac Cocoa)
GitHubに置いてあります [TestSegue](https://github.com/syumipg/selfnote/tree/Segue)


Macのウィンドウ（View）切り替えはSegueを利用するようです。
はじめは何のことやらわからなかったのですが、Xamarinのサンプルプログラム等を解析してみて徐々にイメージがつかめてきたので忘れた場合のためにメモしておきます。

## アプリの概要
1. デバッグすると、MainViewが開きます。
2. テキストフィールドに文字を入力してボタンをクリック。
3. SubViewが開いて、テキストフィールドにMainViewの入力文字列がコピーされます。
4. SubViewのテキストフィールドを変更してCloseボタンをクリック
5. SubViewが閉じて、MainViewに入力データが渡されます。

## 実行画面
### Modalの実行画面
![01TestSegue10_runModal.gif](https://github.com/syumipg/selfnote/wiki/images/01TestSegue10_runModal.gif)

### Sheetの実行画面
![01TestSegue12_runSheet.gif](https://github.com/syumipg/selfnote/wiki/images/01TestSegue12_runSheet.gif)

### Popoverの実行画面
![01TestSegue13_runPopover.gif](https://github.com/syumipg/selfnote/wiki/images/01TestSegue13_runPopover.gif)

### Show
* Windowsの場合のモードレスフォームのようなもの。  
* SubViewを表示した状態でMainViewの操作が可能
![01TestSegue14_runShow.gif](https://github.com/syumipg/selfnote/wiki/images/01TestSegue14_runShow.gif)

## StoryBoardの編集
[GitHubページ](https://github.com/syumipg/selfnote/blob/Segue/readme.md)を参照

## コード
### [SubView.cs](https://github.com/syumipg/selfnote/blob/Segue/TestSegue/SubView.cs)
* 文字列の受け渡しのために「Arg1」文字列プロパティを追加
* ViewWillAppear()をoverrideしてウィンドウ表示されるときにTextFieldにArg1を表示
* 「SubButton_Click」アクションをSubView.designer.csからコピーしてコード実装
* ViewControllerへの参照は「PresentingViewController」で可能（ParentViewControllerはnullでNG）
* Segueのkindが「Show」の場合はnullが帰ってきて参照できないため、SubViewクラスにMainViewを保持するプロパティを作成すると可能
* ViewControllerに文字列プロパティまたはpublic関数を作成するとこれが利用出来る

```
	public partial class SubView : NSViewController
	{
        public string Arg1 { get; set; }    //呼び出し元から受け取るデータ
        /*  //for Show                                    
        private ViewController vc;
        public ViewController ParentView { get { return vc; } set { vc = value; } }
        */
        public SubView(IntPtr handle) : base(handle)
        {
        }
        public override void ViewWillAppear()   //またはViewDidLoad()
        {
            base.ViewWillAppear();
            if (Arg1 != "")
                SubText.StringValue = Arg1;
            else
                SubText.StringValue = "no value from MainView";
        }
        partial void SubButton_Click(Foundation.NSObject sender)
        {
            //Showの場合下をコメントアウト
            ViewController vc = this.PresentingViewController as ViewController;    //呼び出し元のViewControllerインスタンス
            //vc.SubviewValue = SubText.StringValue;    //プロパティに渡す場合
            vc.UpdateLabel(SubText.StringValue);        //呼び出し元のpublic関数にアクセス可能
            this.View.Window.Close();                   //これで閉じることができる
         }
    }
```
### [ViewController.cs](https://github.com/syumipg/selfnote/blob/Segue/TestSegue/ViewController.cs)
* Button_Clickイベント：PerformSegueでSegue1を呼び出す
* PrepareForSegueが呼び出され、segue.IdentifierでSegueを識別できる
* segue.DestinationControllerで新たに呼び出すViewControllerのインスタンスを参照できる

```
        partial void Button_Click(Foundation.NSObject sender)
        {
            //ボタンをドラッグしてSegueを作成した場合は不要
            //PerformSegueは個々のコントロールではなくViewControllerそのものを渡すようだ
            PerformSegue("Segue1", this);    //PrepareForSegueがここで呼ばれる
        }

        public override void PrepareForSegue(NSStoryboardSegue segue, NSObject sender)
        {
            base.PrepareForSegue(segue, sender);
            this.View.Window.Title = segue.Identifier;  //タイトル変えてみた
            SubView sub = segue.DestinationController as SubView;   //参照できる
            sub.Arg1 = TextField1.StringValue;      //プロパティにアクセス可能
            //sub.ParentView = this;  //for Show
        }
        //public string SubviewValue { get; set; }  //プロパティで受け取る場合
        public void UpdateLabel(string str)
        {
            TextField1.StringValue = str;
        }
        public override void ViewWillDisappear()
        {
            base.ViewWillDisappear();
            NSApplication.SharedApplication.Terminate(Self);
        }
```

## 開発環境
* Visual Studio Community for Mac 2017 Ver.7.0.1
* OSX ElCapitan
* MacBook Pro Retina model

## Reference:
* Segue
   1. Xamarin Guides  Mac - Working with Storyboards - [Segue](https://developer.xamarin.com/guides/mac/platform-features/storyboards/indepth/#Segues)
   2. [OS X アプリでStoryboardとSegueを利用する（概略）](http://qiita.com/masakihori/items/ce74f604925f8f66ce1f)

* Segue and parameter
   1. [StoryBoardで画面遷移、画面間の値の受け渡し（とデリゲート）](http://www.aoharu-b.com/cgi/sk/2012/10/storyboard.html)
   2. [Swift初心者メモ Storyboardのsegueで遷移した画面に値を渡すす](http://qiita.com/39_isao/items/5f09c96a8a4c2de7c8fe)
   3. [子ViewControllerから親ViewControllerのパラメータを変更する方法](https://ja.stackoverflow.com/questions/16817/子viewcontrollerから親viewcontrollerのパラメータを変更する方法)

* ViewControllerの参照
   1. [self.parentViewControllerとself.presentingViewControllerについて](http://tyashushi.blogspot.jp/2013/04/selfparentviewcontrollerselfpresentingv.html)

* ViewControllerを閉じる方法
   1. [How to dismiss ViewController in Swift?](https://stackoverflow.com/questions/24668818/how-to-dismiss-viewcontroller-in-swift)
   2. [Can you programmatically close a view controller without a button? - OS X](https://stackoverflow.com/questions/38126755/can-you-programmatically-close-a-view-controller-without-a-button-os-x)