モノトーンの伝説日記

Apex Legends, Splatoon, Programming, and so on...

“iPad 9.7-inch, 10.5-inch の SplitView 2:1” や “iPhone Plus Landscape” にて UISplitView の DetailView の SizeClass の制御を行い,コンテンツ量を抑制する

 タイトル長すぎ。こんにちは,モノトーンです。

 タイトルにも書いた通り,以下のデバイス

  • iPad 9.7-inch (1024x768 -> ratio 2/3: 694x768)
  • iPad 10.5-inch (1112x834 -> ratio 2/3: 782x834)
  • iPhone Plus (736x414)

にて,SplitViewController の挙動について。

UISplitView は一部の狭い DetailView を HorizontalSizeClass を Regular として扱う(特に何も触っていない)

 以下の表は Landscape 時の一覧です (常に PreferredDisplayMode = UISplitViewControllerDisplayMode.AllVisible; 状態です)。

Device Screen Size Master Width Border Size Detail HorSC
iPad mini (7.9-inch) 1/3
iPad 9.7-inch 1/3
320x768 -- -- --
iPad 10.5-inch 1/3 320x834 -- -- --
iPad 12.9-inch 1/3 375x1024 -- -- --
iPhone 3.5-inch 480x320 -- -- --
iPad mini (7.9-inch) 1/2 507x768 -- -- --
iPad mini (7.9-inch) 1/2
iPad 9.7-inch 1/2
551x834 -- -- --
iPhone 4.0-inch 576x320 -- -- --
iPhone 4.7-inch 667x375 -- -- --
iPad 12.9-inch 1/2 678x1024 258pt 1/2pt Regular
iPad mini (7.9-inch) 2/3
iPad 9.7-inch 2/3
694x768 320pt 1/2pt Regular
iPhone Plus (5.5-inch) 736x414 295pt 1/3pt Regular
iPad 10.5-inch 2/3 782x834 320pt 1/2pt Regular
iPad 12.9-inch 2/3 981x1024 375pt 1/2pt Regular
iPad mini (7.9-inch)
iPad 9.7-inch
1024x768 389pt 1/2pt Regular
iPad 10.5-inch 1112x834 423pt 1/2pt Regular
iPad 12.9-inch 1136x1024 519pt 1/2pt Regular

iPad mini は実測値を図っていません。

※ 全機種 iOS 11.3 に基づいた調査です。

※ Detail View Width は「ScreenWidth - (MasterViewWidth + DeviceBorderPixel)」になります。

iPhone Plus を除けば,基本的に Master 側のサイズは横幅の大きさに従って大きくなります。

UISplitView はあくまでも Regular 時に分割画面にするだけで,子の ViewController の Size Class を適切に扱ってくれない。

 従って,Detail View Controller 側では Size Class をオーバーライドして挙動を変更する必要があります。

 以下は Xamarin にて DetailViewController 内で 600pt を境目にして SizeClass を切り替える実装です (上の表で言うと iPad 10.5-inch 2/3 と iPad 12.9-inch 2/3 が境目になる)。

public override UITraitCollection TraitCollection
{
    get
    {
        var traitCollection = base.TraitCollection;

        // ここに追加の条件として SplitViewController が Collapsed でないか判定する必要がある。
        // 実装によってそのあたりの判定は異なると思うので注意。
        if (!_collapsed && View.Bounds.Width < 600F)
        {
            using (var compactTrait = UITraitCollection.FromHorizontalSizeClass(UIUserInterfaceSizeClass.Compact))
            {
                traitCollection = UITraitCollection.FromTraitsFromCollections(new[] { traitCollection, compactTrait });
            }
        }
        return traitCollection;
    }
}

 これで Detail View Controller 側の表示領域が 600pt 以上ある場合は Regular, そうでない場合 Compact に切り替えることが可能です。今後,デバイスが増えたりしても問題なく動作するでしょう。

 ちなみに,Portrait では 1024pt 端末だと 320pt が Master View Width になるので,600pt 以上あるので,基本これぐらいの設定値が妥当だと思われます。

 以上です。