Best way to programmatically detect iPad/iPhone hardware

58,530

Solution 1

I'm answering this now (and at this late date) because many of the existing answers are quite old, and the most Up Voted actually appears to be wrong according to Apples current docs (iOS 8.1, 2015)!

To prove my point, this is the comment from Apples header file (always look at the Apple source and headers):

/*The UI_USER_INTERFACE_IDIOM() macro is provided for use when
  deploying to a version of the iOS less than 3.2. If the earliest
  version of iPhone/iOS that you will be deploying for is 3.2 or
  greater, you may use -[UIDevice userInterfaceIdiom] directly.*/

Therefore, the currently APPLE recommended way to detect iPhone vs. iPad, is as follows:

1) (DEPRECATED as of iOS 13) On versions of iOS PRIOR to 3.2, use the Apple provided macro:

// for iPhone use UIUserInterfaceIdiomPhone
if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)

2) On versions of iOS 3.2 or later, use the property on [UIDevice currentDevice]:

// for iPhone use UIUserInterfaceIdiomPhone
if([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad)

Solution 2

Checking at runtime (your first way) is completely different from #if at compile time. The preprocessor directives won't give you a universal app.

The preferred way is to use Apple's Macro:

if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
{
     // The device is an iPad running iPhone 3.2 or later.
}
else
{
     // The device is an iPhone or iPod touch.
}

Use 3.2 as the base SDK (because the macro is not defined pre 3.2), you can target prior OS versions to get it running on the iPhone.

Solution 3

I like my isPad() function. Same code but keep it out of sight and in only one place.

Solution 4

My solution (works on 3.2+):

#define IS_IPHONE (!IS_IPAD)
#define IS_IPAD (UI_USER_INTERFACE_IDIOM() != UIUserInterfaceIdiomPhone)

then,

if (IS_IPAD)
    // do something

or

if (IS_IPHONE)
    // do something else

Solution 5

In Swift use userInterfaceIdiom instance property as-

if UIDevice.current.userInterfaceIdiom == .phone {
     print("iPhone")
 }

& For other devices -

  switch UIDevice.current.userInterfaceIdiom {
    case .pad:
        print("iPad")
    case .phone:
        print("iPhone")
    case .tv:
        print("TV")
    case .carPlay:
        print("carPlay")
    default: break;
  }
Share:
58,530
Adam Eberbach
Author by

Adam Eberbach

Apparently, this mystery prefers to keep an air of user about them.

Updated on March 31, 2020

Comments

  • Adam Eberbach
    Adam Eberbach over 4 years

    The reason I need to find out is that on an iPad, a UIPickerView has the same height in landscape orientation as it does in portrait. On an iPhone it is different. The iPad programming guide introduces an "idiom" value to UIDevice:

        UIDevice* thisDevice = [UIDevice currentDevice];
        if(thisDevice.userInterfaceIdiom == UIUserInterfaceIdiomPad)
        {
            // iPad
        }
        else
        {
            // iPhone
        }
    

    which works OK while you're in iPad (3.2) but not iPhone (3.1.3) - so it looks like there also needs to be an ifdef to conditionally compile that check, like:

    #if __IPHONE_OS_VERSION_MIN_REQUIRED >= 30200
            UIDevice* thisDevice = [UIDevice currentDevice];
            if(thisDevice.userInterfaceIdiom == UIUserInterfaceIdiomPad)
            {
                // etc.
            }
    #endif
    

    To me that's starting to look very clumsy. What's a better way?