Today ExtensionのiPadでのLandscape時のUI周りについて


## はじめに
自作アプリで Today Extension 追加しました。
iOS 8, iOS 9 で Landscape の Today Extensionの
Width が極端に違うので困ってしまった。
どうしたらいいのか調査。備忘録。

## Today Extension について

通知センターの Today の部分。日本語環境だと **今日** に該当。
ウィジェットを作れる。軽く書いておくと下記。

* Today Extension (Widget)

  - App Extension の一つ(iOS 8 から)
  - 通知センターの Today 部分にアプリの拡張が可能
  - 他のアプリのものもあるので場所の取りすぎ(縦)は不可
  - スクロールも不可
  - ここでキーボード出すのも禁止
  - メモリ不足になると停止することがある
  - 最新の情報を常に表示させること
  - ユーザの使いやすさ重視

### 参考
　- [App Extension Programming Guide](https://developer.apple.com/library/ios/documentation/General/Conceptual/ExtensibilityPG/NotificationCenter.html#//apple_ref/doc/uid/TP40014214-CH11-SW1)
　
* Today Extension について過去まとめたもの(not Qiita)
　- [【iOS】Apple Watch 発売まであと少し! App Extension の練習(Today基礎)](http://milanista224.blogspot.jp/2015/03/appextensiontest-today.html)
　- [【iOS】App Extension の練習(Today基礎2: 値を本体Appから取得)](http://milanista224.blogspot.com/2015/03/appextensiontest-today-2.html)
　
## UI周りは AutoLayout で OK
だと思ってた。ご存知の通り，iOS 9 から通知センターが
2 列になり，極端に少なくなっている。AutoLayout を使って
Portrait 用に作成したものを Landscape の状態で見たら
なんじゃこりゃぁっていう感じになっていた。
iPad Pro は どちらも 2 列表示となっている。
(逆に Portrait の方が狭い...)

Portrait
![portraitiOS9.png](https://qiita-image-store.s3.amazonaws.com/0/88266/ad9e0f15-f538-80ff-05c0-65c8e58aaf04.png "portraitiOS9.png")

Landscape
![landscapeiOS9.png](https://qiita-image-store.s3.amazonaws.com/0/88266/e8ad7e1c-e7f4-9be6-7aa8-931af3da006a.png "landscapeiOS9.png")

ひどいものである。Landscape 時の表示合わすと今度は
Portrait 時の表示がなんとも言えない感じになってしまう。
動的に確保するのも面倒だなと思ったので，Landscape 時だけ
左のマージンを 0 にすることで応急処置した。

## 緊急処置
App Extension の制約で UIApplication のインスタンスを保持する
sharedApplication にアクセスができないため，縦横の長さを使った，
古典的な比較にしました。iOS 7 は 縦横逆になるのですが，
App Extension は iOS 8 からの機能なので気にしなくて済む。

App Extension Programming Guide によると，
> 自分の計算の挿入値を取得するには、 widgetMarginInsetsForProposedMarginInsets:メソッドを実装します

とのことなので，このメソッド内に実装する。

```obj-c:Objective-C
// 余白設定(上の余白，左の余白，下の余白，右の余白)
- (UIEdgeInsets)widgetMarginInsetsForProposedMarginInsets:(UIEdgeInsets)defaultMarginInsets
{
    // iOS 7 は App Extension が使えないので問題なし
    if ([Util isIOS9]) {
        // iOS 9
        if(self.view.frame.size.width > self.view.frame.size.height) {
            // iPad Pro のとき
            if ([Util isIPADPRO]) {
                // ちょっと広めなのでマージン取ろう
                UIEdgeInsets insets = UIEdgeInsetsMake(0, defaultMarginInsets.left, 0, 0);
                return insets;
            } else {
                // iPad Air, iPad mini のとき
                // Landscape のときが狭いのでマージンを0にする
                // Landscapeのとき(0, 0, 0, 0)を返す
                return UIEdgeInsetsZero;
            }

        } else {
            // iPad Pro のとき
            if ([Util isIPADPRO]) {
                // Portrait のときが狭いのでマージンを0にする
                return UIEdgeInsetsZero;
            } else {
                // iPad Air, iPad mini のとき
                // Portrait のときは通常通りのマージンをあける
                UIEdgeInsets insets = UIEdgeInsetsMake(0, defaultMarginInsets.left, 0, 0);
                return insets;
            }
        }
        
    } else {
        // iOS 8
        UIEdgeInsets insets = UIEdgeInsetsMake(0, defaultMarginInsets.left, 0, 0);
        return insets;
    }
}

```

defaultMarginInsets.left についてですが，
iOS によって異なるようです。

|端末|iOS|Portrait|Landscape|
|:--|:--:|:--:|:--:|
|iPad Air|iOS 8|57|57|
|iPad Air|iOS 9|44|44|
|iPad Pro|iOS 9|44|44|

役立つか分からないけど調べたので書いておく。


結果は，
Portrait
![portraitsiOS9_2.png](https://qiita-image-store.s3.amazonaws.com/0/88266/7cfc96d9-e45d-becb-c1a2-e2a7f515ee18.png "portraitsiOS9_2.png")

Landscape
![landscapeiOS9_2.png](https://qiita-image-store.s3.amazonaws.com/0/88266/a55653e1-da8e-fd41-6e7d-8169fd330f9f.png "landscapeiOS9_2.png")

良さそうには見えますが，今度は Portrait がバランス悪くなった。
いろいろマージン調整してベストポジションを見つけていくことになりそう。
センターから AutoLayout かけたら Portrait のときも
真ん中に寄っちゃうだろうし，外からかけても離れて真ん中ガラ空き
みたいになるよなー。

## おわりに
iOS 9 の Landscape 時の使える範囲がかなり狭くなったので
どうしたらバランス良く表示できるかについて調査した。マージンを
いじるのはあまり良くない気がする。コードで AutoLayout 対応
するのが一番なのかもしれない。iPad Pro も入ってきたからなぁ。
私はこう対応してるよーとかあったらご教授お願いいたします。

ご覧いただきありがとうございました！！