如何在Swift中以编程方式检查iPhone 4和iPhone 5的屏幕大小

62

我需要将这个Objective-C代码转为Swift。有人对如何进行转换有什么建议吗?

if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
{
    CGSize result = [[UIScreen mainScreen] bounds].size;
    if(result.height == 480)
    {
        // iPhone Classic
    }
    if(result.height == 568)
    {
        // iPhone 5
    }
}

请看:https://dev59.com/h1YO5IYBdhLWcg3wMO1y#52821290 - ale_stro
13个回答

182

Xcode 12.4 • Swift 5.3 或更高版本

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)

1
为什么不使用else if,或者更好的是使用枚举等方式来命名高度? - Oliver Atkinson
nativeBoundsbounds有什么不同?文档中说var nativeBounds: CGRect { get } // Native bounds of the physical screen in pixels,但我并不真正理解它们之间的区别。 - Hlung
2
像素是您的手机实际显示的像素数量。边界是您可以在点中绘制的实际区域(远少于实际像素)。 - Leo Dabus
感谢!我也自己找到了。从 iPhone5s 模拟器打印出来的内容如下: nativeBounds: (0.0, 0.0, 640.0, 1136.0) bounds: (0.0, 0.0, 320.0, 568.0) - Hlung
2
这太棒了。 - backslash-f
显示剩余6条评论

28

使用UIScreen扩展的替代解决方案(适用于iOS 8及更高版本):

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

使用方法:

if UIScreen.mainScreen().sizeType == .iPhone4 {
    // Make specific layout for small devices.
}

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将提供设备的高度。 通过使用此值,我们可以检查特定的iPhone设备。


你应该使用 nativeBounds 属性。bounds 属性的结果取决于设备的方向。 - Leo Dabus
@LeoDabus NativeBounds和bounds有什么区别? - Sudhi 9135
边界:此矩形是在当前坐标空间中指定的,该坐标空间考虑了设备生效的任何接口旋转。因此,在设备在纵向和横向方向之间旋转时,此属性的值可能会发生变化。 - Leo Dabus
NATIVEBOUNDS:物理屏幕的边界矩形,以像素为单位测量。该矩形基于设备处于纵向朝上方向。此值在设备旋转时不会更改。 - Leo Dabus
@LeoDabus 感谢您提供宝贵的信息和时间。 - Sudhi 9135

8

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

打印(“screenType:”,UIDevice.current.screenType.rawValue)


7

以下是我使用 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
}

5

已更新以适配iPhone 14、14 Plus、14 Pro和14 Pro Max

已更新以适配iPhone 13 Mini、13、13 Pro和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
        }
    }
}


4
只是为了补充https://dev59.com/5V4c5IYBdhLWcg3wj7B6#27776671的内容。

允许您编写

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

请参见以下内容。
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
}}

2

Xcode 11和Swift 4.2

如果您想要使用屏幕类型设置一个框架,那么这对我来说可以正常工作。

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


    }

1
尝试使用以下内容:

创建一个名为UIViewController+Extension.swift的文件,并将以下代码放入其中:

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

并在您的viewController.swift中像这样使用它:

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

如果你想的话,可以添加更多情况。享受它。


1
为什么要在“runOnTheDeviceType”中使用完成块?只需使用普通的返回值即可,它不是异步的。 - rmaddy

1

除了提出的方法外,另一种做法是以如下方式使用结构体。

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
}

请告诉我它是否有帮助。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接