yaakaito.org

Segueでのオブジェクトのやりとりとか

Objective-C, Storyboard, iOS

こんにちは!うきょーです! UIのコード書くのがだるいので今更感満載でStoryboardを始めました! Storyboard出来がよくて、iOSっぽいUIを作る分にはぽちぽちしていけば作れて便利だなーという感じです。

で、ViewController間でのオブジェクトのやりとりにはやっぱコードが必要なので、そこのメモ。 大体よく使うのはpushViewControllerModalTableViewあたりだと思うので、その3つあたりを書く。

別にそれぞれで大きく変わる訳でもないと思うので、最初に貼っておくととりあえずこんな感じのStoryboard作った。

めんどくさいので最初のVCをSSViewController、遷移先をSSSecondViewControllerにしてある。

基本

prepareForSegue:sender:というのを使うらしい、これは遷移元の方に書く。 遷移先から戻すときはdelegate、両方prepareForSegue:sender:でいけんのかなーとか思ったけどそうではないらしい。

PushVC

コードはここ

遷移元の方でprepareForSegue:sender:を定義してあげる。SegueにはTopToSecondって名前が付けてある。

1
2
3
4
5
6
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {

    if ([segue.identifier isEqualToString:@"TopToSecond"]) {
        NSLog(@"%@", segue.destinationViewController);
    }
}

こうすると遷移するときに、ここが呼ばれるので、Segue名で分岐する。 segue.destinationViewControllerに遷移先のViewControllerのインスタンスが入っているので、ここでよしなにする。 別にそんなにめんどくさくなさそう。

次、戻る時。普通にdelegateでやる。

1
2
3
@protocol SSSecondViewControllerDelegate
- (void)willBack:(id)obj;
@end

適当にプロトコルつくって、さっきのところで関連付ける。

1
2
3
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    ((SSSecondViewController *)segue.destinationViewController).delegate = self;
}

で、戻ってくるときにこれを呼べばいいんだけど、そういう感じのイベントがあるのかと思ったら別になかった。 軽く調べてみた感じだけど、viewWillDisappearでやればよさげ。

1
2
3
4
5
- (void)viewWillDisappear:(BOOL)animated {

    [super viewWillDisappear:animated];
    [self.delegate willBack:@{@"A" : @"HOGE"}];
}

Modal

コードはここ

pushVCと大差ない。使ってないけど、いままでself.presentedViewControllerだったのがself.presentingViewControllerに変わるらしい、紛らわしい。

モーダル閉じるところまでStoryboardで面倒みてほしい気分なんだけど、やりかたがよくわからなかった。

1
2
3
- (IBAction)touchDismiss:(id)sender {
    [self dismissViewControllerAnimated:YES completion:nil];
}

TableView

コードはここ

戻すところは一緒だけど、indexPathを知る必要があるので一手間増える。 試してみたら、prepareForSegue:sender: -> tableView:didSelectRowAtIndexPath: という順になってて、それはどうなんだろうという気持ちになった。

1
2
3
4
5
6
7
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {

    if ([segue.identifier isEqualToString:@"TopToSecond"]) {
        NSLog(@"%@", segue.destinationViewController);
        NSLog(@"%@", self.tableView.indexPathForSelectedRow);
    }
}

こんな感じで、あとはよしなに。

まとめ

別にprepareForSegue:sender:じゃなくともよいのではという気がしたりしたけど、 そう書けと言われてるっぽいし長い物に巻かれてそう書く事にした。 いろいろ書けてしまいそうなので、早めにルール作っちゃうのがいいのかなーという感じ。

あとこれどういう名前付ければいいのかよくわからん、Segueってサフィックスは付けた気がいい気がする。