user189804
user189804

Reputation:

Best way to programmatically detect iPad/iPhone hardware

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?

Upvotes: 51

Views: 60389

Answers (10)

Suhit Patil
Suhit Patil

Reputation: 12023

extension UIDevice {
   
   static var isIPad: Bool {
      return UIDevice.current.userInterfaceIdiom == .pad
   }
}

Usage:

if UIDevice.isIPad {
    // Perform iPad related logic here
}

Upvotes: 1

Cliff Ribaudo
Cliff Ribaudo

Reputation: 9039

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)

Upvotes: 38

Jack
Jack

Reputation: 14329

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;
  }

Upvotes: 4

andyqee
andyqee

Reputation: 3221

BOOL isIpad()
{
    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
        return YES;
    }
    return NO;
}

Upvotes: 0

Topsakal
Topsakal

Reputation: 447

If 1- you already have the app installed into your device, 2- you change its build settings to be a 'Universal' app, 3- install the app to your device on top of the pre-existing app (without deleting the previous one)

You might find that the solutions provided here to detect iPhone/iPad do not work. First, delete the app that was 'only' for iPad/iPhone and install it fresh to your device.

Upvotes: 0

lewisanderson
lewisanderson

Reputation: 231

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

Upvotes: 15

Damon
Damon

Reputation: 1

If you are using features that are not backwards compatible, I found the best way for me is to create a #define in the pre-compiled header. Example:

#if __IPHONE_OS_VERSION_MAX_ALLOWED > __IPHONE_3_2
#define USING_4_X
#endif

Then in your code, you can do this:

BOOL exists = NO;
#ifdef USING_4_X        
exists = [SomeObject someMethod:[url lastPathComponent]];
#else
exists = [SomeObject someMethod:[[url path] lastPathComponent]];
#endif

Upvotes: 0

Sanniv
Sanniv

Reputation: 1877

Put this method in your App Delegate so that you can call it anywhere using [[[UIApplication sharedApplication] delegate] isPad]

-(BOOL)isPad
{
    BOOL isPad;
    NSRange range = [[[UIDevice currentDevice] model] rangeOfString:@"iPad"];
    if(range.location==NSNotFound)
    {
        isPad=NO;


    }
    else {
        isPad=YES;
    }

    return isPad;
}

Upvotes: 0

Eiko
Eiko

Reputation: 25632

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.

Upvotes: 63

progrmr
progrmr

Reputation: 77191

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

Upvotes: 16

Related Questions