iOS определяет, находится ли пользователь на iPad

260

У меня есть приложение, которое работает на iPhone и iPod Touch, оно может работать на Retina iPad и все такое, но нужно выполнить одну настройку. Мне нужно определить, является ли текущее устройство iPad. Какой код я могу использовать, чтобы определить, использует ли пользователь iPad, UIViewControllerи затем что-то изменить соответствующим образом?

Альберт Реншоу
источник

Ответы:

589

Существует немало способов проверить, является ли устройство iPad. Это мой любимый способ проверить, является ли устройство на самом деле iPad:

if ( UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad )
{
    return YES; /* Device is iPad */
}

Как я использую это

#define IDIOM    UI_USER_INTERFACE_IDIOM()
#define IPAD     UIUserInterfaceIdiomPad

if ( IDIOM == IPAD ) {
    /* do something specifically for iPad. */
} else {
    /* do something specifically for iPhone or iPod touch. */
}   

Другие примеры

if ( [(NSString*)[UIDevice currentDevice].model hasPrefix:@"iPad"] ) {
    return YES; /* Device is iPad */
}

#define IPAD     (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
if ( IPAD ) 
     return YES;

Для решения Swift см. Этот ответ: https://stackoverflow.com/a/27517536/2057171

WrightsCS
источник
23
То, как вы используете его, не так эффективно, как могло бы быть. UI_USER_INTERFACE_IDIOM()эквивалентно ([[UIDevice currentDevice] respondsToSelector:@selector(userInterfaceIdiom)] ? [[UIDevice currentDevice] userInterfaceIdiom] : UIUserInterfaceIdiomPhone). Вы могли бы быть лучше кэшировать результат где - то: BOOL iPad = UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad; … if (iPad) ….
Марсело Кантос
7
Я бы использовал hasPrefix вместо isEqualToString в вашем последнем методе. Таким образом, код работает и на симуляторе.
elbuild
18
Свифт:if UIDevice.currentDevice().userInterfaceIdiom == .Pad
Пан
2
Боготворное использование макросов. Отличный способ запутать ваш код.
gnasher729
2
@ gnasher729 500+ человек склонны не соглашаться с вами. Вместо ярких комментариев, почему бы вам не дать свой собственный ответ, поскольку вы думаете, что у вас есть лучший способ сделать это.
WrightsCS
162

В Swift вы можете использовать следующие равенства для определения типа устройства в универсальных приложениях:

UIDevice.current.userInterfaceIdiom == .phone
// or
UIDevice.current.userInterfaceIdiom == .pad

Использование тогда будет примерно таким:

if UIDevice.current.userInterfaceIdiom == .pad {
    // Available Idioms - .pad, .phone, .tv, .carPlay, .unspecified
    // Implement your logic here
}
Jeehut
источник
3
Я редактирую ссылку на ваш ответ в принятый ответ. (Таким образом, вы получаете кредит тоже). Несмотря на то, что это объективный вопрос, многие люди, просматривающие этот вопрос, приходят из Google и могут искать решение Swift! : D
Альберт Реншоу
1
Спасибо, @AlbertRenshaw. Я тоже так думал. :) Кстати: я не думаю, что целью вопроса было спросить специально для Objective-C, но для iOS (который был Obj-C в тот момент). По крайней мере, я ожидал найти ответ на этот вопрос и для Свифта.
Jeehut
Привет @sevensevens, спасибо за ваш отзыв. Я только что попробовал это, и это сработало для меня в XCode 7.2 для iOS 9 в симуляторе. Какую версию XCode вы используете? Может быть, это не работает на старых XCodes? Документы говорят userInterfaceIdiom: «Доступно в iOS 3.2 и более поздних версиях». так что это не должно быть проблемой.
Jeehut
Или, может быть, вы используете приложение только для iPhone на симуляторе iPad? В этом случае это могло бы объяснить путаницу, но я думаю, что на реальных устройствах она должна вести себя так же. Как отмечает @Yunus Недим Мехел в комментариях @Richards, ситуация вернется .Phoneвместо .Pad.
Jeehut
Извините - симулятор был установлен на iPhone. Должен прекратить вносить изменения в 2
часа
35

Это часть UIDevice с iOS 3.2, например:

[UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad
Ричард
источник
4
идиома, как правило, лучше, но если вы запускаете приложение для iphone на iPad, это вернет UIUserInterfaceIdiomPhone.
Юнус Недим Мехел
25

Вы также можете использовать это

#define IPAD UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad
...
if (IPAD) {
   // iPad
} else {
   // iPhone / iPod Touch
}
зябко
источник
24

UI_USER_INTERFACE_IDIOM()возвращает iPad только в том случае, если приложение предназначено для iPad или Universal. Если это приложение для iPhone работает на iPad, то это не так. Поэтому вы должны вместо этого проверить модель.

malhal
источник
15

Будьте внимательны: если ваше приложение предназначено только для устройства iPhone, iPad, работающий в режиме, совместимом с iphone, вернет false для следующего утверждения:

#define IPAD     UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad

Правильный способ обнаружения физического устройства iPad:

#define IS_IPAD_DEVICE      ([(NSString *)[UIDevice currentDevice].model hasPrefix:@"iPad"])
вершина горы
источник
15

Я обнаружил, что какое-то решение не работает для меня в симуляторе в Xcode. Вместо этого это работает:

ObjC

NSString *deviceModel = (NSString*)[UIDevice currentDevice].model;

if ([[deviceModel substringWithRange:NSMakeRange(0, 4)] isEqualToString:@"iPad"]) {
    DebugLog(@"iPad");
} else {
    DebugLog(@"iPhone or iPod Touch");
}

стриж

if UIDevice.current.model.hasPrefix("iPad") {
    print("iPad")
} else {
    print("iPhone or iPod Touch")
}

Также в «Других примерах» в Xcode модель устройства возвращается как «iPad Simulator», так что вышеприведенная настройка должна разобраться с этим.

Энди Дэвис
источник
Может быть, Apple обновила симулятор, чтобы сказать что-то вроде «iPad simulator» или «iPad 2.1» или что-то ... если это тот случай, который вы могли бы использовать hasSuffix:@"iPad"вместо isEqualToString@"iPad"... ваш лучший выбор - зарегистрировать модель устройства, которую симулятор возвращает и уходит оттуда ...
Альберт Реншоу
8

Много способов сделать это в Swift :

Мы проверим модель ниже (мы можем только выполнить поиск с учетом регистра здесь):

class func isUserUsingAnIpad() -> Bool {
    let deviceModel = UIDevice.currentDevice().model
    let result: Bool = NSString(string: deviceModel).containsString("iPad")
    return result
}

Мы проверяем модель ниже (мы можем выполнить поиск с учетом регистра / без учета здесь):

    class func isUserUsingAnIpad() -> Bool {
        let deviceModel = UIDevice.currentDevice().model
        let deviceModelNumberOfCharacters: Int = count(deviceModel)
        if deviceModel.rangeOfString("iPad",
                                     options: NSStringCompareOptions.LiteralSearch,
                                     range: Range<String.Index>(start: deviceModel.startIndex,
                                                                end: advance(deviceModel.startIndex, deviceModelNumberOfCharacters)),
                                     locale: nil) != nil {
            return true
        } else {
            return false
        }
   }

UIDevice.currentDevice().userInterfaceIdiomниже возвращает только iPad, если приложение для iPad или Universal. Если это приложение для iPhone, запущенное на iPad, то оно не будет. Поэтому вы должны вместо этого проверить модель. :

    class func isUserUsingAnIpad() -> Bool {
        if UIDevice.currentDevice().userInterfaceIdiom == UIUserInterfaceIdiom.Pad {
            return true
        } else {
            return false
        }
   }

Этот фрагмент ниже не компилируется, если класс не наследует UIViewController, иначе он работает просто отлично. Независимо от того, UI_USER_INTERFACE_IDIOM()только возвращает iPad, если приложение для iPad или Universal. Если это приложение для iPhone, запущенное на iPad, то оно не будет. Поэтому вы должны вместо этого проверить модель. :

class func isUserUsingAnIpad() -> Bool {
    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiom.Pad) {
        return true
    } else {
        return false
    }
}
Король-Мастер
источник
2
Я не думаю, что есть необходимость переписывать старые ответы на вопросы, помеченные Objective-C, чтобы быстро.
Кристиан Шнорр
4
Я определенно думаю, что мой ответ полезен, потому что, во-первых, все ответы разбросаны по переполнению стека. Во-вторых, то, что работало со старыми версиями iOS, иногда некорректно работает с iOS 8 и выше. Поэтому я проверил эти решения, и этот ответ может быть очень полезным. Так что я не согласен с вами вообще.
Король-волшебник
Кроме того, синтаксис в Swift отличается. Таким образом, для каждого всегда полезно сделать интеллектуальную копию вставки ответа и понять конкретные современные гайки и болты.
Король-волшебник
8

*

В Swift 3.0

*

 if UIDevice.current.userInterfaceIdiom == .pad {
        //pad
    } else if UIDevice.current.userInterfaceIdiom == .phone {
        //phone
    } else if UIDevice.current.userInterfaceIdiom == .tv {
        //tv
    } else if UIDevice.current.userInterfaceIdiom == .carPlay {
        //CarDisplay
    } else {
        //unspecified
    }
Ашок Р
источник
8

Многие ответы хороши, но я использую это в Swift 4

  1. Создать константу

    struct App {
        static let isRunningOnIpad = UIDevice.current.userInterfaceIdiom == .pad ? true : false
    }
    
  2. Используйте как это

    if App.isRunningOnIpad {
        return load(from: .main, identifier: identifier)
    } else {
        return load(from: .ipad, identifier: identifier)
    }
    

Изменить: как предложено Cœur просто создать расширение на UIDevice

extension UIDevice {
    static let isRunningOnIpad = UIDevice.current.userInterfaceIdiom == .pad ? true : false
}
Рохит Сисодиа
источник
3
Зачем беспокоиться о Appструктуре, когда вы можете сделать то же самое с UIDeviceрасширением?
Cœur
3

Вы можете проверить rangeOfString, чтобы увидеть, что слово iPad существует следующим образом.

NSString *deviceModel = (NSString*)[UIDevice currentDevice].model;

if ([deviceModel rangeOfString:@"iPad"].location != NSNotFound)  {
NSLog(@"I am an iPad");
} else {
NSLog(@"I am not an iPad");
}
LearningGuy
источник
["I am not an iPad" rangeOfString:@"iPad"].location != NSNotFoundвозвращает истину.
Cœur
2

Еще один Swifty путь:

//MARK: -  Device Check
let iPad = UIUserInterfaceIdiom.Pad
let iPhone = UIUserInterfaceIdiom.Phone
@available(iOS 9.0, *) /* AppleTV check is iOS9+ */
let TV = UIUserInterfaceIdiom.TV

extension UIDevice {
    static var type: UIUserInterfaceIdiom 
        { return UIDevice.currentDevice().userInterfaceIdiom }
}

Использование:

if UIDevice.type == iPhone {
    //it's an iPhone!
}

if UIDevice.type == iPad {
    //it's an iPad!
}

if UIDevice.type == TV {
    //it's an TV!
}
Авиэль Гросс
источник
2

В Swift 4.2 и Xcode 10

if UIDevice().userInterfaceIdiom == .phone {
    //This is iPhone
} else if UIDevice().userInterfaceIdiom == .pad { 
    //This is iPad
} else if UIDevice().userInterfaceIdiom == .tv {
    //This is Apple TV
}

Если вы хотите обнаружить конкретное устройство

let screenHeight = UIScreen.main.bounds.size.height
if UIDevice().userInterfaceIdiom == .phone {
    if (screenHeight >= 667) {
        print("iPhone 6 and later")
    } else if (screenHeight == 568) {
        print("SE, 5C, 5S")
    } else if(screenHeight<=480){
        print("4S")
    }
} else if UIDevice().userInterfaceIdiom == .pad { 
    //This is iPad
}
IOS
источник
1

Почему так сложно? Вот как я это делаю ...

Свифт 4:

var iPad : Bool {
    return UIDevice.current.model.contains("iPad")
}

Таким образом, вы можете просто сказать, if iPad {}

Раффус
источник
1
Примечание: этот вопрос был задан в 2012 году
Альберт Реншоу
0

Для последних версий iOS просто добавьте UITraitCollection:

extension UITraitCollection {

    var isIpad: Bool {
        return horizontalSizeClass == .regular && verticalSizeClass == .regular
    }
}

а затем в течение UIViewControllerпросто проверить:

if traitCollection.isIpad { ... }
Бартломей Семанчик
источник
4
Это также работает, когда iPad-приложение находится в режиме разделения экрана? Тогда класс горизонтального размера будет компактным.
Оливер
0
if(UI_USER_INTERFACE_IDIOM () == UIUserInterfaceIdiom.pad)
 {
            print("This is iPad")
 }else if (UI_USER_INTERFACE_IDIOM () == UIUserInterfaceIdiom.phone)
 {
            print("This is iPhone");
  }
Раджеш Шарма
источник