62

I need to replace this Objective-C to Swift. Does anyone have any suggestions on how to transfer it?

if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
{
    CGSize result = [[UIScreen mainScreen] bounds].size;
    if(result.height == 480)
    {
        // iPhone Classic
    }
    if(result.height == 568)
    {
        // iPhone 5
    }
}
Caleb Kleveter
  • 11,170
  • 8
  • 62
  • 92
SantoshMaurya
  • 649
  • 1
  • 6
  • 3

13 Answers13

182

Xcode 12.4 • Swift 5.3 or later

extension UIDevice {
    var iPhoneX: Bool { UIScreen.main.nativeBounds.height == 2436 }
    var iPhone: Bool { UIDevice.current.userInterfaceIdiom == .phone }
    var iPad: Bool { UIDevice().userInterfaceIdiom == .pad }
    enum ScreenType: String {
        case iPhones_4_4S = "iPhone 4 or iPhone 4S"
        case iPhones_5_5s_5c_SE = "iPhone 5, iPhone 5s, iPhone 5c or iPhone SE"
        case iPhones_6_6s_7_8 = "iPhone 6, iPhone 6S, iPhone 7 or iPhone 8"
        case iPhones_6Plus_6sPlus_7Plus_8Plus = "iPhone 6 Plus, iPhone 6S Plus, iPhone 7 Plus or iPhone 8 Plus"
        case iPhones_6Plus_6sPlus_7Plus_8Plus_Simulators = "iPhone 6 Plus, iPhone 6S Plus, iPhone 7 Plus or iPhone 8 Plus Simulators"
        case iPhones_X_XS_12MiniSimulator = "iPhone X or iPhone XS or iPhone 12 Mini Simulator"
        case iPhone_XR_11 = "iPhone XR or iPhone 11"
        case iPhone_XSMax_ProMax = "iPhone XS Max or iPhone Pro Max"
        case iPhone_11Pro = "iPhone 11 Pro"
        case iPhone_12Mini_13Mini = "iPhone 12 Mini or iPhone 13 Mini"
        case iPhone_12_12Pro_13Pro_14 = "iPhone 12 or iPhone 12 Pro or iPhone 13 Pro or iPhone 14"
        case iPhone_12ProMax_13ProMax_14Plus = "iPhone 12 Pro Max or iPhone 13 Pro Max or iPhone 14 Plus"
        case iPhone_14Pro = "iPhone 14 Pro"
        case iPhone_14ProMax = "iPhone 14 Pro Max"
        case unknown
    }
    var screenType: ScreenType {
        switch UIScreen.main.nativeBounds.height {
        case 1136: return .iPhones_5_5s_5c_SE
        case 1334: return .iPhones_6_6s_7_8
        case 1792: return .iPhone_XR_11
        case 1920: return .iPhones_6Plus_6sPlus_7Plus_8Plus
        case 2208: return .iPhones_6Plus_6sPlus_7Plus_8Plus_Simulators
        case 2340: return .iPhone_12Mini_13Mini
        case 2426: return .iPhone_11Pro
        case 2436: return .iPhones_X_XS_12MiniSimulator
        case 2532: return .iPhone_12_12Pro_13Pro_14
        case 2556: return .iPhone_14Pro
        case 2688: return .iPhone_XSMax_ProMax
        case 2778: return .iPhone_12ProMax_13ProMax_14Plus
        case 2796: return .iPhone_14ProMax
        default: return .unknown
        }
    }
}

print("screenType:", UIDevice.current.screenType)
Jatin
  • 92
  • 7
Leo Dabus
  • 229,809
  • 59
  • 489
  • 571
  • 1
    why not use else if, or even better name the heights using an enum or such? – Oliver Atkinson Jan 05 '15 at 13:24
  • how different is `nativeBounds` from `bounds`? The doc said `var nativeBounds: CGRect { get } // Native bounds of the physical screen in pixels`, but I don't really understand the difference. – Hlung Jun 09 '15 at 05:35
  • 2
    Pixels is how many actual pixels your phone can display. Bounds is the actual area you have to draw in points (much less than the actual pixels) – Leo Dabus Jun 09 '15 at 05:42
  • Thanks! Found this out myself too. Printing this from iPhone5s simulator. `nativeBounds: (0.0, 0.0, 640.0, 1136.0)` `bounds: (0.0, 0.0, 320.0, 568.0)` – Hlung Jun 09 '15 at 17:01
  • I tested this on my own iphone 6 +, Says "unknown" – user2722667 Sep 07 '15 at 22:31
  • @user2722667 it works fine for me here with the simulator – Leo Dabus Sep 14 '15 at 02:48
  • @user2722667 I have just tested it with a real device and the problem was that all plus devices they do a downsampling so to fix this issue you need to test two different resolutions, one for the simulator 2208 and one for the real devices 1920 – Leo Dabus Oct 03 '17 at 00:54
  • for those who also would like to expand this functionality for different iPad sizes: you can add the following code to enum ScreenType: case iPad_5thGen_Air_Air2_Pro97inch = "iPad 5th Generation, iPad Air, iPad Air 2, iPad Pro 9.7-inch" case iPad_7thGeneration = "iPad 7th Generation" case iPad_Air3rdGen_Pro105inch = "iPad Air 3rd Generation, iPad Pro 10.5-inch" case iPadPro_11inch = "iPad Pro 11-inch" case iPadPro_129inch = "iPad Pro 12.9-inch" – tiw Mar 04 '20 at 12:59
  • And the following cases to the nativeBounds.height switch: case 2048: return .iPad_5thGen_Air_Air2_Pro97inch case 2160: return .iPad_7thGeneration case 2224: return .iPad_Air3rdGen_Pro105inch case 2388: return .iPadPro_11inch case 2732: return .iPadPro_129inch – tiw Mar 04 '20 at 13:00
28

Alternative solution with UIScreen extension ( iOS 8 and later):

extension UIScreen {

    enum SizeType: CGFloat {
        case Unknown = 0.0
        case iPhone4 = 960.0
        case iPhone5 = 1136.0
        case iPhone6 = 1334.0
        case iPhone6Plus = 1920.0
    }

    var sizeType: SizeType {
        let height = nativeBounds.height
        guard let sizeType = SizeType(rawValue: height) else { return .Unknown }
        return sizeType
    }
}

Usage:

if UIScreen.mainScreen().sizeType == .iPhone4 {
    // Make specific layout for small devices.
}
Vlad Papko
  • 13,184
  • 4
  • 41
  • 57
10
if UIDevice().userInterfaceIdiom == .Phone {
    switch UIScreen.mainScreen().bounds.size.height{
    case 480:
        print("iPhone 4S")
    case 568:
        print("iPhone 5")
    default:
        print("other models")
    }
}

UIScreen.mainScreen().bounds.size.height will provide the height of the device. By using this value we can check the particular iphone device.

Tunaki
  • 132,869
  • 46
  • 340
  • 423
Sudhi 9135
  • 745
  • 8
  • 17
  • You should use nativeBounds. Bounds property result depends on the device orientation – Leo Dabus Mar 19 '17 at 14:14
  • @LeoDabus What is the difference between NativeBounds and bounds. – Sudhi 9135 Mar 20 '17 at 04:41
  • BOUNDS: This rectangle is specified in the current coordinate space, which takes into account any interface rotations in effect for the device. Therefore, the value of this property may change when the device rotates between portrait and landscape orientations. – Leo Dabus Mar 20 '17 at 04:50
  • NATIVEBOUNDS: The bounding rectangle of the physical screen, measured in pixels. This rectangle is based on the device in a portrait-up orientation. This value does not change as the device rotates. – Leo Dabus Mar 20 '17 at 04:50
  • @LeoDabus Thank you for valuable information and your time. – Sudhi 9135 Mar 20 '17 at 06:40
8

New Update with iPhone XS, iPhone XS Max & iPhone XR

extension UIDevice {
    var iPhoneX: Bool {
        return UIScreen.main.nativeBounds.height == 2436
    }
    var iPhone: Bool {
        return UIDevice.current.userInterfaceIdiom == .phone
    }
    enum ScreenType: String {
        case iPhone4_4S = "iPhone 4 or iPhone 4S"
        case iPhones_5_5s_5c_SE = "iPhone 5, iPhone 5s, iPhone 5c or iPhone SE"
        case iPhones_6_6s_7_8 = "iPhone 6, iPhone 6S, iPhone 7 or iPhone 8"
        case iPhones_6Plus_6sPlus_7Plus_8Plus = "iPhone 6 Plus, iPhone 6S Plus, iPhone 7 Plus or iPhone 8 Plus"
        case iPhoneXR = "iPhone XR"
        case iPhoneX_iPhoneXS = "iPhone X,iPhoneXS"
        case iPhoneXSMax = "iPhoneXS Max"
        case unknown
    }
    var screenType: ScreenType {
        switch UIScreen.main.nativeBounds.height {
        case 960:
            return .iPhone4_4S
        case 1136:
            return .iPhones_5_5s_5c_SE
        case 1334:
            return .iPhones_6_6s_7_8
        case 1792:
            return .iPhoneXR
        case 1920, 2208:
            return .iPhones_6Plus_6sPlus_7Plus_8Plus
        case 2436:
            return .iPhoneX_iPhoneXS
        case 2688:
            return .iPhoneXSMax
        default:
            return .unknown
        }
    }
}

print("screenType:", UIDevice.current.screenType.rawValue)

Sujal
  • 1,205
  • 1
  • 11
  • 24
7

Here's how I do it with Xcode 10 + Swift 4 + iPhone XS/XS Max/XR

struct ScreenSize {
    static let SCREEN_WIDTH         = UIScreen.main.bounds.size.width
    static let SCREEN_HEIGHT        = UIScreen.main.bounds.size.height
    static let SCREEN_MAX_LENGTH    = max(ScreenSize.SCREEN_WIDTH, ScreenSize.SCREEN_HEIGHT)
    static let SCREEN_MIN_LENGTH    = min(ScreenSize.SCREEN_WIDTH, ScreenSize.SCREEN_HEIGHT)
}

struct DeviceType {
    static let IS_IPHONE_4_OR_LESS  = UIDevice.current.userInterfaceIdiom == .phone && ScreenSize.SCREEN_MAX_LENGTH < 568.0
    static let IS_IPHONE_5          = UIDevice.current.userInterfaceIdiom == .phone && ScreenSize.SCREEN_MAX_LENGTH == 568.0
    static let IS_IPHONE_6          = UIDevice.current.userInterfaceIdiom == .phone && ScreenSize.SCREEN_MAX_LENGTH == 667.0
    static let IS_IPHONE_6P         = UIDevice.current.userInterfaceIdiom == .phone && ScreenSize.SCREEN_MAX_LENGTH == 736.0
    static let IS_IPHONE_X          = UIDevice.current.userInterfaceIdiom == .phone && ScreenSize.SCREEN_MAX_LENGTH == 812
    static let IS_IPAD              = UIDevice.current.userInterfaceIdiom == .pad && ScreenSize.SCREEN_MAX_LENGTH   == 1024.0
    static let IS_IPAD_PRO          = UIDevice.current.userInterfaceIdiom == .pad && ScreenSize.SCREEN_MAX_LENGTH   == 1366.0
    static let IS_IPHONE_XSMAX      = UIDevice.current.userInterfaceIdiom == .phone && ScreenSize.SCREEN_MAX_LENGTH == 2688
    static let IS_IPHONE_XR         = UIDevice.current.userInterfaceIdiom == .phone && ScreenSize.SCREEN_MAX_LENGTH == 1792
}
John Riselvato
  • 12,854
  • 5
  • 62
  • 89
5

Updated for iPhone 14, 14 Plus, 14 Pro and 14 Pro Max

Updated for iPhone 13 Mini, 13, 13 Pro and 13 Pro Max

public extension UIDevice {
    
    
    var iPhone: Bool { UIDevice.current.userInterfaceIdiom == .phone }
    var iPad: Bool { UIDevice().userInterfaceIdiom == .pad }
    
    enum ScreenType: String {
        case iPhones_4_4S = "iPhone 4 or iPhone 4S"
        case iPhones_5_5s_5c_SE = "iPhone 5, iPhone 5s, iPhone 5c or iPhone SE"
        case iPhones_6_6s_7_8 = "iPhone 6, iPhone 6S, iPhone 7 or iPhone 8"
        case iPhones_6Plus_6sPlus_7Plus_8Plus = "iPhone 6 Plus, iPhone 6S Plus, iPhone 7 Plus or iPhone 8 Plus"
        case iPhones_X_XS = "iPhone X or iPhone XS"
        case iPhone_XR_11 = "iPhone XR or iPhone 11"
        case iPhone_XSMax_ProMax = "iPhone XS Max or iPhone Pro Max"
        case iPhone_11Pro = "iPhone 11 Pro"
        case iPhone_12_12Pro_13_13Pro_14 = "iPhone 12 or 12 Pro or 13 or 13 Pro or 14"
        case iPhone_14Pro = "iPhone 14 Pro"
        case iPhone_12ProMax_13ProMax_14Plus = "iPhone 12 Pro Max or 13 Pro Max or 14 Plus"
        case iPhone_14ProMax = "iPhone 14 Pro Max"
        case iPhone12Mini_13Mini = "iPhone 12 Mini or 13 Mini"
        case unknown
    }
    
    var screenType: ScreenType {
        guard iPhone else { return .unknown }
        switch UIScreen.main.nativeBounds.height {
        case 960:
            return .iPhones_4_4S
        case 1136:
            return .iPhones_5_5s_5c_SE
        case 1334:
            return .iPhones_6_6s_7_8
        case 1792:
            return .iPhone_XR_11
        case 1920, 2208:
            return .iPhones_6Plus_6sPlus_7Plus_8Plus
        case 2340:
            return .iPhone12Mini_13Mini
        case 2426:
            return .iPhone_11Pro
        case 2436:
            return .iPhones_X_XS
        case 2532:
            return .iPhone_12_12Pro_13_13Pro_14
        case 2688:
            return .iPhone_XSMax_ProMax
        case 2778:
            return .iPhone_12ProMax_13ProMax_14Plus
        case 2556:
            return .iPhone_14Pro
        case 2796:
            return .iPhone_14ProMax
        default:
            return .unknown
        }
    }
}

3llomi
  • 688
  • 1
  • 10
  • 18
4

Just to add to https://stackoverflow.com/a/27776671/1766242

Allows you to write

if UIDevice.isScreen35inch() {
    // Do something to fit small screen
} else {
    // do something else for larger screens
}

See below

extension UIDevice {
var iPhone: Bool {
    return UIDevice().userInterfaceIdiom == .Phone
}
enum ScreenType: String {
    case iPhone4
    case iPhone5
    case iPhone6
    case iPhone6Plus
    case Unknown
}
var screenType: ScreenType? {
    guard iPhone else { return nil }
    switch UIScreen.mainScreen().nativeBounds.height {
    case 960:
        return .iPhone4
    case 1136:
        return .iPhone5
    case 1334:
        return .iPhone6
    case 2208:
        return .iPhone6Plus
    default:
        return nil
    }
}

// helper funcs
static func isScreen35inch() -> Bool {
    return UIDevice().screenType == .iPhone4
}

func isScreen4inch() -> Bool {
    return UIDevice().screenType == .iPhone5
}

func isScreen47inch() -> Bool {
    return UIDevice().screenType == .iPhone6
}

func isScreen55inch() -> Bool {
    return UIDevice().screenType == .iPhone6Plus
}}
Community
  • 1
  • 1
maninvan
  • 890
  • 9
  • 10
2

Xcode 11 and Swift 4.2

If you want a set frame using the screen type. Its work fine to me

enum ScreenType: String {
        case iPhones_4_4S = "iPhone 4 or iPhone 4S"
        case iPhones_5_5s_5c_SE = "iPhone 5, iPhone 5s, iPhone 5c or iPhone SE"
        case iPhones_6_6s_7_8 = "iPhone 6, iPhone 6S, iPhone 7 or iPhone 8"
        case iPhones_6Plus_6sPlus_7Plus_8Plus = "iPhone 6 Plus, iPhone 6S Plus, iPhone 7 Plus or iPhone 8 Plus"
        case iPhones_X_XS = "iPhone X or iPhone XS"
        case iPhone_XR = "iPhone XR"
        case iPhone_XSMax = "iPhone XS Max"
        case unknown
    }

    var screenType: ScreenType {
        switch UIScreen.main.nativeBounds.height {
        case 960:
            return .iPhones_4_4S
        case 1136:
            return .iPhones_5_5s_5c_SE
        case 1334:
            return .iPhones_6_6s_7_8
        case 1792:
            return .iPhone_XR
        case 1920, 2208:
            return .iPhones_6Plus_6sPlus_7Plus_8Plus
        case 2436:
            return .iPhones_X_XS
        case 2688:
            return .iPhone_XSMax
        default:
            return .unknown
        }
    }

override func viewWillLayoutSubviews() {
        if screenType == .iPhone_XR || screenType == .iPhones_X_XS || screenType == .iPhone_XSMax {
            self.contentView.frame = CGRect(x: 0, y: 0, width: UIScreen.main.bounds.size.width, height: UIScreen.main.bounds.size.height - 95)
        } else {
            self.contentView.frame = CGRect(x: 0, y: 0, width: UIScreen.main.bounds.size.width, height: UIScreen.main.bounds.size.height - 64)
        }


    }
Srinivasan_iOS
  • 972
  • 10
  • 12
1

In addition to the proposed way, One way of doing this is to use the struct in following way.

struct ScreenSize
{
  static let SCREEN_WIDTH         = UIScreen.main.bounds.size.width
  static let SCREEN_HEIGHT        = UIScreen.main.bounds.size.height
  static let SCREEN_MAX_LENGTH    = max(ScreenSize.SCREEN_WIDTH, ScreenSize.SCREEN_HEIGHT)
  static let SCREEN_MIN_LENGTH    = min(ScreenSize.SCREEN_WIDTH,    ScreenSize.SCREEN_HEIGHT)
}

struct DeviceType
{
  static let IS_IPHONE_4_OR_LESS  = UIDevice.current.userInterfaceIdiom == .phone && ScreenSize.SCREEN_MAX_LENGTH < 568.0
  static let IS_IPHONE_5          = UIDevice.current.userInterfaceIdiom == .phone && ScreenSize.SCREEN_MAX_LENGTH == 568.0
  static let IS_IPHONE_6          = UIDevice.current.userInterfaceIdiom == .phone && ScreenSize.SCREEN_MAX_LENGTH == 667.0
  static let IS_IPHONE_6P         = UIDevice.current.userInterfaceIdiom == .phone && ScreenSize.SCREEN_MAX_LENGTH == 736.0
  static let IS_IPAD              = UIDevice.current.userInterfaceIdiom == .pad && ScreenSize.SCREEN_MAX_LENGTH   == 1024.0
  static let IS_IPAD_PRO          = UIDevice.current.userInterfaceIdiom == .pad && ScreenSize.SCREEN_MAX_LENGTH   == 1366.0
}

Let me know if it helps.

tendstoZero
  • 146
  • 3
1

try to use this:

Create a UIViewController+Extension.swift file: and put into below code:

enum DeviceTypeModel{
    case iphoneX
    case iphone8Plus
    case iphone8
    case iphoneSE //SE is the like iphone 5 and iphone 5s
    case iphone4s
}

extension UIViewController{
    func runOnTheDeviceType(_ completion: (DeviceTypeModel) -> Void) {
        if UIDevice().userInterfaceIdiom == .phone{
            switch UIScreen.main.nativeBounds.height{
            case 2436:
                completion(.iphoneX)
            case 1920:
                completion(.iphone8Plus)
            case 1334:
                completion(.iphone8)
            case 1136:
                completion(.iphoneSE)
            default:
                completion(.iphone4s)
            }
        }
    }
}

and use it in your viewController.swift like this:

class ChatViewController: UIViewController{
      override func viewDidLoad() {
        super.viewDidLoad()
          runOnTheDeviceType { devices in
            switch devices{
            case .iphoneSE:
                //do something
            case .iphone4s:
                //do something
            default:
                //do something
            }
        }
      }
}

you can add more cases if you want to do it. Enjoy it.

gandhi Mena
  • 2,115
  • 1
  • 19
  • 20
  • 1
    Why would you use a completion block for `runOnTheDeviceType`? Just use a normal return value, it's not asynchronous. – rmaddy May 18 '18 at 17:40
0

Answer by Leo fixed it for me. Here is some sample class for all the Xamarin.IOS devs :)

public static class ScreenHelper
{
    public enum ScreenSizeType
    { 
        iPhone4_4s,
        iPhone5_5s_5c_SE,
        iPhone6_6s_7_8,
        iPhone6plus_6sPlus_7Plus_8Plus,
        iPhoneX,
        unknown
    }

    public static bool IsIphone
    {
        get
        {
            return UIDevice.CurrentDevice.UserInterfaceIdiom == UIUserInterfaceIdiom.Phone;
        }
    }

    public static bool IsNarrowScreen
    {
        get
        {
            return UIScreen.MainScreen.NativeBounds.Width <= 640;
        }
    }

    public static ScreenSizeType CurrentScreenType
    { 
        get
        {
            switch ((int)UIScreen.MainScreen.NativeBounds.Height)
            { 
                case 960:
                    return ScreenSizeType.iPhone4_4s;
                case 1136:
                    return ScreenSizeType.iPhone5_5s_5c_SE;
                case 1334:
                    return ScreenSizeType.iPhone6_6s_7_8;
                case 1920:
                case 2208:
                    return ScreenSizeType.iPhone6plus_6sPlus_7Plus_8Plus;
                case 2436:
                    return ScreenSizeType.iPhoneX;
                default:
                    return ScreenSizeType.unknown;
            }
        }
    }
}
Jelle
  • 365
  • 3
  • 11
0

Quick Update based on Leo's answer for the iPhone 12/12 Pro/12 Mini/12 Pro Max

// handle device screen types and sizes
public extension UIDevice {
    
    var iPhoneX: Bool { UIScreen.main.nativeBounds.height == 2436 }
    var iPhone: Bool { UIDevice.current.userInterfaceIdiom == .phone }
    var iPad: Bool { UIDevice().userInterfaceIdiom == .pad }
    
    enum ScreenType: String {
        case iPhones_4_4S = "iPhone 4 or iPhone 4S"
        case iPhones_5_5s_5c_SE = "iPhone 5, iPhone 5s, iPhone 5c or iPhone SE"
        case iPhones_6_6s_7_8 = "iPhone 6, iPhone 6S, iPhone 7 or iPhone 8"
        case iPhones_6Plus_6sPlus_7Plus_8Plus = "iPhone 6 Plus, iPhone 6S Plus, iPhone 7 Plus or iPhone 8 Plus"
        case iPhones_X_XS_12mini = "iPhone X or iPhone XS"
        case iPhone_XR_11 = "iPhone XR or iPhone 11"
        case iPhone_XSMax_ProMax = "iPhone XS Max or iPhone Pro Max"
        case iPhone_11Pro = "iPhone 11 Pro"
        case iPhone_12_12Pro = "iPhone 12 or 12 Pro"
        case iPhone_12ProMax = "iPhone 12 Pro Max"
        case unknown
    }
    
    var screenType: ScreenType {
        guard iPhone else { return .unknown }
        switch UIScreen.main.nativeBounds.height {
        case 960:
            return .iPhones_4_4S
        case 1136:
            return .iPhones_5_5s_5c_SE
        case 1334:
            return .iPhones_6_6s_7_8
        case 1920, 2208:
            return .iPhones_6Plus_6sPlus_7Plus_8Plus
        case 2426:
            return .iPhone_11Pro
        case 2436:
            return .iPhones_X_XS_12mini
        case 2532:
            return .iPhone_12_12Pro
        case 2688:
            return .iPhone_XSMax_ProMax
        case 2778:
            return .iPhone_12ProMax
        default:
            return .unknown
        }
    }
}
cvocvo
  • 1,586
  • 2
  • 23
  • 38
-6

You can also try this below code:

 if (IS_IPHONE4) {
        imgHeight.constant = 150;
    }
    else if (IS_IPAD) {
        imgHeight.constant = 300;
    }
    else if (IS_IPHONE5) {
        imgHeight.constant = 170;
    }
    else {
        imgHeight.constant = 200;
    }

Thanks.

Gangani Roshan
  • 583
  • 1
  • 8
  • 25
  • 2
    1. The question is asking how to translate Objective-C code into Swift code so this answer doesn't help. 2. This answer references unknown variables such as `IS_IPHONE4`. – rmaddy May 18 '18 at 17:43