Androidアプリ開発に慣れ親しんだ者がiOSアプリ開発と触れ合うための比較表

[DMM.com Advent Calendar 2018](https://qiita.com/advent-calendar/2018/dmm) 21日目を担当します、 @mii-chang です:information_desk_person_tone1:
2018年新卒入社して、電子チケットのアプリを開発しています。
学生時代は主にAndroidアプリの開発をしていたのですが、入社してからはiOSの開発にも関わるようになりました。

#はじめに
iOSの開発に関わるにあたり、ざっと理解を深めるために、色々と調べていましたが、
なんとなく、今までiOSをやっていた人がAndroidを始める話は多く見つかるが、その逆のAndroidをやっていた人がiOSを始める話があまり見当たらなかったような気がしました。
AndroidのアレみたいなのをiOSで実装したいんだけど！どうしたら！という場面が結構あって困ったので、
今更感はありますが、私が今まででiOSでどう実装するのか困ったもの、使ってみて便利だったものなどをまとめてみようと思いました:writing_hand:

クロスプラットフォームな感じがイマドキっぽいですが、ネイティブアプリもまだまだたくさん作られていると思うので…新しくiOSを始める人に少しでも役立てれば嬉しいです…！


# 基礎名称編
## Activity
###iOSでは
ざっくり理解としては、iOSでは`ViewController`がAndroidのActivityと同じような働きを持っています。画面操作ができるものです。
ここは、MVCだとかMVPだとかMVVMだとか話し出すと長くなってしまいそうなので、ここまでにとどめておきます。


# ライフサイクル編
AndroidとiOSのライフサイクルを比べたとき、**だいたい近い動き**をしているなという箇所をまとめました。
完全に一緒ではないので、注意です。
## onCerate
Activityが初めて生成されたタイミングでなにかしたいとき、Androidならば`onCreate`内で処理を行います。
###iOSでは
`loadView`と`viewDidLoad`がだいたいonCreateに近い動きをしています。
`loadView`は、Viewを読み込むときに呼ばれ、
`viewDidLoad`は`loadView`が呼ばれた後に1度だけ呼ばれます。

## onResume
Avtivityが表示されたタイミングでなにかしたいとき、Androidならば`onResume`内で処理を行います。
###iOSでは
`viewWillAppear`と`viewDidAppear`がだいたいonResumeに近い動きをしています。
`viewWillAppear`は、Viewが表示される直前に呼ばれます。
`viewDidAppear`は、Viewが表示された直後に呼ばれます。

## onPause
別のActivityが呼ばれたタイミングでなにかしたいとき、Androidならば`onPause`内で処理を行います。
###iOSでは
`viewWillDisappear`がだいたいonPauseに近い動きをしています。
`viewWillDisappear`は、Viewが非表示になる直前に呼ばれます。

## onStop
別のActivityが非表示になったタイミングでなにかしたいとき、Androidならば`onStop`内で処理を行います。
###iOSでは
`viewDidDisappear`がだいたいonStopに近い動きをしています。
`viewDidDisappear`は、Viewが非表示になった直後に呼ばれます。

## onDestroy
Activityが破棄されたタイミングでなにかしたいとき、Androidならば`onDestroy`内で処理を行います。
###iOSでは
Androidで言うActivityの破棄系の処理（onPause~onDestroy）を、`viewWillDisappear`と`viewDidDisappear`が行っています。onDestroyっぽい、破棄されたタイミング、という分類で考えると、該当するものはない？かもでした。
Viewが非表示になるときには、`viewWillDisappear`→`viewDidDisappear`と呼ばれるということがわかればOKかな？

------
iOSのライフサイクルを理解する上でスーパー役に立った記事は[こちら](https://qiita.com/motokiee/items/0ca628b4cc74c8c5599d)です。

# UI編
##レイアウト系
###ConstraintLayout
Androidで相対的な位置関係で制約をつけてViewを組みたいときは`ConstraintLayout`を使います。
####iOSでは
`AutoLayout`を使います。
Androidと同じように、各View同士に制約(constraint)をつけて行きます。

###LinearLayout
Androidで縦か横一列にViewを並べたいときは、`LinearLayout`を使います。
####iOSでは
`StackView`を使います。
LinearLayoutのように縦か横一列にViewを並べることができ、この中のView同士に制約をつけることもできます。
Android的に言うと、LinearLayoutが親で、子にConstraintLayoutが入っているような状態です。
StackView登場以前は、大量のConstraintでゴチャついていたStoryBoardですが、これの登場によりスッキリきれいに、わかりやすくなりました。
ViewとViewの間にあらたなViewを差し込むなども簡単になって本当に感動しました。

-----
StackViewを理解する上でスーパー役に立った記事は[こちら](https://qiita.com/yucovin/items/ff58fcbd60ca81de77cb)です。

## リスト系
### ListView
なにかを一列に並べたいとき、Androidでは`ListView`を使います。
ここでは、ListViewのリストアイテムを複雑にカスタマイズした物というよりは、**超単純に一列に要素を並べる**ようなリスト表示を想像してください。
####iOSでは
`TableView`を使います。
`TableView`は、ごくシンプルなリスト表示をするのに適しています。

### RecyclerView(カスタマイズしたリスト)
もう最近はリスト表示するなら`RecyclerView`かなと思うので、分けてみました。
`RecyclerView`というか、リストアイテムを複雑にカスタマイズして、リスト表示（スクロール表示）させたい場合です。
####iOSでは
`ScrollView`+`StackView`を使います。
何かをスクロール表示させたいとき、スクロール領域は`ScrollView`で、各アイテムは`StackView`で実装します。

##Fragment
いまやAndroidに欠かせない存在となったFragmentですが、今回は、Activityの中で複数の画面を入れ替えたり
する場合を想像してください。
###iOSでは
`xib`を使い、ViewControllerの中で入れ替えました。
`xib`は、Androidでいうxml(レイアウトファイル)のようなものです。
私はFragmentに紐づくxmlを想定し、それぞれの画面をxibで作成し、Activityのような役割である、ViewControllerの中で、表示するxibを入れ替えてFragmentのような動きで画面切り替えを実現しました。

#### サンプル
ボタンを押してxibを切り替えるサンプルです

```Swift
class ViewController: UIViewController {
    
    @IBOutlet weak var container:UIView!
    let redView:UIView = UINib(nibName: "RedView", bundle:nil).instantiate(withOwner: self, options: nil)[0] as! UIView
    let blueView:UIView = UINib(nibName: "BlueView", bundle:nil).instantiate(withOwner: self, options: nil)[0] as! UIView
    var changeFlag = false
    
    override func viewDidLoad() {
        super.viewDidLoad()
        changeView()
    }
    
    
    func changeView() {
        let width = self.container.bounds.size.width
        let height = self.container.bounds.size.height
        let frame = CGRect(x:0, y:0, width:width, height:height)
        if changeFlag {
            blueView.removeFromSuperview()
            redView.frame = frame
            container.addSubview(redView)
            changeFlag = false
        } else {
            redView.removeFromSuperview()
            blueView.frame = frame
            container.addSubview(blueView)
            changeFlag = true
        }
    }
    
    @IBAction func click(sender:AnyObject){
        changeView()
    }
}
```

![image](https://qiita-image-store.s3.amazonaws.com/0/93899/05ab88c3-49f4-d6e1-5a8d-008ac5dd790d.png)

Buttonの入っているViewが固定Viewで、containerが可変Viewです。

こんな感じで、　xibからViewを作って、表示フラグによって入れ替えることで、Fragmentで画面切り替えチックな動きを実現しました。


<img src="https://qiita-image-store.s3.amazonaws.com/0/93899/a09e4395-9c2e-9257-f2eb-8059726bfadd.gif" width=50%>


これは、今回この記事を書こうと思ったきっかけの実装で、かなり悩みに悩んだ結果なのですが、もっと良いやり方があったら是非コメントなどで教えてください:bow:

# まとめ
##ライフサイクル系
|Android|iOS|
|:------|:--|
|onCerate|loadView / viewDidLoad|
|onResume|viewWillAppear / viewDidAppear|
|onStop|viewDidDisappear|
|onDestroy|-|

##UI系
|Android|iOS|
|:-------------|:--|
|ConstraintLayout|AutoLayout(Constraint)|
|LinearLayout|StackView|
|ListView(シンプル一列並び)|TableView|
|RecyclerView(カスタマイズしたリスト)|ScrollView　+　StackView|
|Fragment|xibをいれかえ|


# おわりに
OS間で、いいところ、不便なところはそれぞれありますが、どちらか得意な方でイメージを作っておくと、同時に理解が深まりやすいかな？と思いました。
私のように、Androidのアレ、iOSでどうするんだ〜！と悩んでいる方の参考になったら嬉しいし、これを読んでiOSエンジニアの方がAndroid開発にも興味を持っていただけたら嬉しいです!:apple: