iOS 检测用户是否在 iPad 上

iOS detect if user is on an iPad

提问人:Albert Renshaw 提问时间:4/16/2012 最后编辑:General GrievanceAlbert Renshaw 更新时间:6/9/2023 访问量:168590

问:

我有一个在 iPhone 和 iPod Touch 上运行的应用程序,它可以在 Retina iPad 上运行,但需要进行一次调整。我需要检测当前设备是否是 iPad。我可以使用什么代码来检测用户是否在我的 iPad 中使用,然后相应地更改某些内容?UIViewController

iOS 版 Swift Objective-C iPad

评论


答:

606赞 WrightsCS 4/16/2012 #1

有很多方法可以检查设备是否是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

评论

25赞 Marcelo Cantos 2/16/2013
你使用它的方式并不像它应该的那样有效。 等同于 。最好将结果缓存在某个位置:.UI_USER_INTERFACE_IDIOM()([[UIDevice currentDevice] respondsToSelector:@selector(userInterfaceIdiom)] ? [[UIDevice currentDevice] userInterfaceIdiom] : UIUserInterfaceIdiomPhone)BOOL iPad = UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad; … if (iPad) …
7赞 elbuild 9/27/2013
我会在您的最后一个方法中使用 hasPrefix 而不是 isEqualToString。这样,代码也可以在模拟器上运行。
20赞 Pang 8/9/2014
迅速:if UIDevice.currentDevice().userInterfaceIdiom == .Pad
2赞 gnasher729 12/2/2017
宏的可怕使用。混淆代码的好方法。
3赞 WrightsCS 12/2/2017
@gnasher729 500+ 人倾向于不同意你的观点。与其说是尖刻的评论,不如提供自己的答案,因为你认为你有更好的方法来做到这一点。
18赞 Andy Davies 11/14/2012 #2

我发现某些解决方案在 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 模拟器”的形式返回,因此上面的调整应该可以解决这个问题。

评论

0赞 Albert Renshaw 11/15/2012
也许苹果更新了模拟器,说“iPad模拟器”或“iPad 2.1”之类的东西......如果是这样的话,你可以用它来代替......最好的办法是记录模拟器返回的设备型号,然后从那里开始......hasSuffix:@"iPad"isEqualToString@"iPad"
38赞 Richard 11/22/2012 #3

这是 iOS 3.2 的 UIDevice 的一部分,例如:

[UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad

评论

4赞 Yunus Nedim Mehel 12/19/2013
idiom 通常更好,但如果您在 iPad 上运行 iphone 应用程序,这将返回 UIUserInterfaceIdiomPhone。
25赞 Chilly 1/28/2013 #4

你也可以用这个

#define IPAD UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad
...
if (IPAD) {
   // iPad
} else {
   // iPhone / iPod Touch
}
24赞 malhal 1/28/2014 #5

UI_USER_INTERFACE_IDIOM()仅当应用适用于 iPad 或通用时才返回 iPad。如果它是在 iPad 上运行的 iPhone 应用程序,那么它不会。因此,您应该检查模型。

3赞 LearningGuy 9/3/2014 #6

您可以检查 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");
}

评论

0赞 Cœur 2/6/2018
["I am not an iPad" rangeOfString:@"iPad"].location != NSNotFound返回 true。
193赞 Jeehut 12/17/2014 #7

Swift 中,您可以使用以下等号来确定通用 App 上的设备类型

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
}

评论

3赞 Albert Renshaw 12/17/2014
我正在将您的答案链接编辑为已接受的答案。(这样你也可以得到信用)。尽管这是一个客观的问题,但很多查看这个问题的人都来自 Google,他们可能正在寻找 Swift 解决方案!:D
1赞 Jeehut 12/17/2014
谢谢你,@AlbertRenshaw。我也是这么认为的。:)顺便说一句:我不认为这个问题的目的不是专门针对 Objective-C,而是针对 iOS(当时是 Obj-C)。至少我本来希望在这个问题下也能为斯威夫特找到答案。
0赞 Jeehut 12/26/2015
嗨,@sevensevens,感谢您的反馈。我刚刚尝试了一下,它确实在模拟器中针对 iOS 7.2 的 XCode 9 中对我有用。您使用的是哪个版本的 XCode?也许它不适用于较旧的 XCodes?文档说是“在 iOS 3.2 及更高版本中可用”,所以这应该不是问题。userInterfaceIdiom
0赞 Jeehut 12/26/2015
或者,您可能在iPad模拟器上运行仅限iPhone的应用程序?在这种情况下,这可以解释这种混淆——但我认为它也应该在真实设备上以这种方式运行。正如@Yunus Nedim Mehel在@Richards回答的评论中指出的那样,这种情况将再次出现,而不是..Phone.Pad
0赞 sevensevens 12/26/2015
对不起 - 已将模拟器设置为 iPhone。必须在凌晨 2 点停止更改
8赞 King-Wizard 6/3/2015 #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。如果它是在 iPad 上运行的 iPhone 应用程序,那么它不会。因此,您应该检查模型。:

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

如果类没有继承 ,下面的代码片段不会编译,否则它就可以正常工作。仅当应用程序适用于 iPad 或 Universal 时,才会返回 iPad。如果它是在 iPad 上运行的 iPhone 应用程序,那么它不会。因此,您应该检查模型。:UIViewControllerUI_USER_INTERFACE_IDIOM()

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

评论

2赞 Christian Schnorr 7/2/2015
我认为没有必要将标记为 Objective-C 的问题的旧答案重写为 swift。
4赞 King-Wizard 7/3/2015
我绝对认为我的答案是有用的,因为首先所有答案都分散在堆栈溢出上。其次,适用于旧版本 iOS 的方法有时不适用于 iOS 8 及更高版本。所以我测试了这些解决方案,这个答案可能非常有用。所以我完全不同意你的看法。
0赞 King-Wizard 7/3/2015
最重要的是,Swift 中的语法是不同的。因此,对每个人来说,对答案进行智能复制粘贴并了解特定的最新螺母和螺栓总是有用的。
0赞 Chris Hayes 7/3/2015
这个答案正在 meta 上讨论。
16赞 peak 6/12/2015 #9

请注意:如果您的应用仅面向 iPhone 设备,则以 iPhone 兼容模式运行的 iPad 将返回以下语句的 false:

#define IPAD     UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad

检测物理iPad设备的正确方法是:

#define IS_IPAD_DEVICE      ([(NSString *)[UIDevice currentDevice].model hasPrefix:@"iPad"])
2赞 Aviel Gross 7/5/2016 #10

另一种 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!
}
8赞 Ashok R 10/9/2016 #11

*

在 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
    }
0赞 Bartłomiej Semańczyk 2/6/2017 #12

对于最新版本的 iOS,只需添加:UITraitCollection

extension UITraitCollection {

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

然后在检查中:UIViewController

if traitCollection.isIpad { ... }

评论

5赞 Oliver 6/27/2017
当 iPad-App 处于分屏模式时,这是否也有效?然后水平大小类将是紧凑的。
1赞 Rajesh Sharma 4/27/2017 #13
if(UI_USER_INTERFACE_IDIOM () == UIUserInterfaceIdiom.pad)
 {
            print("This is iPad")
 }else if (UI_USER_INTERFACE_IDIOM () == UIUserInterfaceIdiom.phone)
 {
            print("This is iPhone");
  }
2赞 The Ruffus 9/21/2017 #14

为什么这么复杂?我就是这样做的......

斯威夫特 4:

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

这样你就可以说if iPad {}

评论

1赞 Albert Renshaw 9/21/2017
注意:这个问题是在 2012 年提出的
11赞 Rohit Sisodia 1/4/2018 #15

许多答案都很好,但我在 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)
    }
    

编辑:根据建议,只需在UIDevice上创建一个扩展

extension UIDevice {
    static let isRunningOnIpad = UIDevice.current.userInterfaceIdiom == .pad ? true : false
}

评论

3赞 Cœur 2/6/2018
当您可以对扩展执行相同的操作时,为什么要为结构而烦恼呢?AppUIDevice
5赞 Naresh 10/12/2018 #16

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
}
1赞 Cope 12/6/2020 #17

我不认为这些答案中的任何一个都符合我的需要,除非我从根本上误解了什么。

我有一个应用程序(最初是一个 iPad 应用程序),我想在 iPad 和 Mac 上的 Catalyst 下运行它。我正在使用 plist 选项来缩放 Mac 界面以匹配 iPad,但如果合理,我想迁移到 AppKit。在 Mac 上运行时,我相信上述所有方法都告诉我我在 iPad 上。Catalyst 的假货非常彻底。

对于大多数问题,我确实理解代码应该假装它在 iPad 上,从而在 Mac 上运行。一个例外是,滚动选取器在 Catalyst 下的 Mac 上不可用,但在 iPad 上可用。我想弄清楚是在运行时创建 UIPickerView 还是执行不同的操作。运行时选择至关重要,因为我希望使用单个二进制文件长期在 iPad 和 Mac 上运行,同时充分利用每个版本支持的 UI 标准。

这些 API 会给普通的 Catalyst 前读者带来潜在的误导性结果。例如,在 Mac 上的 Catalyst 下运行时返回。用户界面惯用语 API 也保持着同样的错觉。[UIDevice currentDevice].model@"iPad"

我发现你真的需要更深入地研究。我从以下信息开始:

NSString *const deviceModel = [UIDevice currentDevice].model;
NSProcessInfo *const processInfo = [[NSProcessInfo alloc] init];
const bool isIosAppOnMac = processInfo.iOSAppOnMac;  // Note: this will be "no" under Catalyst
const bool isCatalystApp = processInfo.macCatalystApp;

然后,您可以将这些查询与表达式相结合,例如整理出我面临的各种微妙之处。就我而言,如果指示的 是 ,我明确希望避免制作 UIPickerView,这与有关界面习语的“误导性”信息或由 和 维持的错觉无关。[deviceModel hasPrefix: @"iPad"]isCatalystApptrueisIosAppOnMacdeviceModel

现在我很好奇,如果我将 Mac 应用程序移动到我的 iPad 边车上运行会发生什么......

评论

1赞 Albert Renshaw 12/7/2020
苹果的疏忽真大!我想知道这是否是一个错误?感谢分享