【iPhoneXR,Xs,XsMaxの判別対応】Nativeコード内での判別方法(解像度での判別)


はじめに

はい。相変わらずのiPhone X対応です。タイトル通りですが、今までXだった場合の判別は画面解像度で判別していましたが、新機種のXs,XR,XsMaxが続々登場ということで対応をすることに。。。
相も変わらず画面解像度での判別です。(他に便利な方法などございましたらコメントよろしくお願いいたします。)
Qiitaとかに記事があるかと探したのですが意外とないので寄稿しますー。

各端末解像度について

各端末の解像度は下記のサイトで確認及びシュミレータでの動作確認をしました。
https://www.dorapro.co.jp/engineerblog/?p=255

実行環境

Xs,XR,XsMaxをシュミレートする場合、Xcodeをbeta版に更新する必要があります。
https://developer.apple.com/jp/support/beta-software/

ソースコード

Device.m

#define ScreenHeight [UIScreen mainScreen].nativeBounds.size.height
#define ScreenWidth [UIScreen mainScreen].nativeBounds.size.width
#define ScreenScale [UIScreen mainScreen].scale

// iphoneX以上の端末を判別
+ (BOOL)isIphoneXOver {
    return (Device.isIphoneX || Device.isIphoneXs || Device.isIphoneXR || UIDevice.isIphoneXsMax);
}

+ (BOOL)isIphoneX {
    return [self checkIPhoneSize:1125.0 height:2436.0 scale:3.0];
}

+ (BOOL)isIphoneXs {
    return [self checkIPhoneSize:1125.0 height:2436.0 scale:3.0];
}

+ (BOOL)isIphoneXR {
    return [self checkIPhoneSize:828.0 height:1792.0 scale:2.0];
}

+ (BOOL)isIphoneXsMax {
    return [self checkIPhoneSize:1242.0 height:2688.0 scale:3.0];
}

+ (BOOL)checkIphoneSize:(CGFloat)width height:(CGFloat)height scale:(CGFloat)scale {
    static BOOL result = NO;
    if (@available(iOS 11.0, *)) {
        if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) {
            result = ((ScreenWidth == width && ScreenHeight == height) && ScreenScale == scale);
        }
    }
    return result;
}

Gist

iphoneX以上の場合の判別をしたかったのでisIphoneXOverというメソッドを追加してX以上の端末の場合Trueが返るような実装にしています。各端末で判別がした場合はisIphoneX~以降のメソッドを使用してもらえればと思います。一つ注意する点があり、XとXsは画面解像度とScaleが一緒なので厳密にXとXsの判別ができていないので注意が必要です。(誰か判別方法知ってたらコメントオナシャス。。。)

まとめ

これから先さらにノッチが付いたAppleの端末が登場するかと思いますが、その場合でも(Appleが判別方法を公開しない限り)こういった対応が必要かと思います。おそらく解像度での判別が一番コストが低く簡単な方法だと考えました。(逆に解像度以外での判別方法をご存知の方がいましたらコメント等よろしくお願いいたします。)