Swiftgram/submodules/Display/Source/DeviceMetrics.swift
2020-02-18 03:43:19 +04:00

274 lines
9.5 KiB
Swift

import UIKit
public enum DeviceType {
case phone
case tablet
}
public enum DeviceMetrics: CaseIterable, Equatable {
case iPhone4
case iPhone5
case iPhone6
case iPhone6Plus
case iPhoneX
case iPhoneXSMax
case iPad
case iPadPro10Inch
case iPadPro11Inch
case iPadPro
case iPadPro3rdGen
case unknown(screenSize: CGSize, statusBarHeight: CGFloat, onScreenNavigationHeight: CGFloat?)
public static var allCases: [DeviceMetrics] {
return [
.iPhone4,
.iPhone5,
.iPhone6,
.iPhone6Plus,
.iPhoneX,
.iPhoneXSMax,
.iPad,
.iPadPro10Inch,
.iPadPro11Inch,
.iPadPro,
.iPadPro3rdGen
]
}
public init(screenSize: CGSize, statusBarHeight: CGFloat, onScreenNavigationHeight: CGFloat?) {
var screenSize = screenSize
if screenSize.width > screenSize.height {
screenSize = CGSize(width: screenSize.height, height: screenSize.width)
}
let additionalSize = CGSize(width: screenSize.width, height: screenSize.height + 20.0)
for device in DeviceMetrics.allCases {
if let _ = onScreenNavigationHeight, device.onScreenNavigationHeight(inLandscape: false, systemOnScreenNavigationHeight: nil) == nil {
if case .tablet = device.type {
if screenSize.height == 1024.0 && screenSize.width == 768.0 {
} else {
continue
}
} else {
continue
}
}
let width = device.screenSize.width
let height = device.screenSize.height
if ((screenSize.width.isEqual(to: width) && screenSize.height.isEqual(to: height)) || (additionalSize.width.isEqual(to: width) && additionalSize.height.isEqual(to: height))) {
self = device
return
}
}
self = .unknown(screenSize: screenSize, statusBarHeight: statusBarHeight, onScreenNavigationHeight: onScreenNavigationHeight)
}
public var type: DeviceType {
switch self {
case .iPad, .iPadPro10Inch, .iPadPro11Inch, .iPadPro, .iPadPro3rdGen:
return .tablet
case let .unknown(screenSize, _, _) where screenSize.width >= 768.0 && screenSize.height >= 1024.0:
return .tablet
default:
return .phone
}
}
var screenSize: CGSize {
switch self {
case .iPhone4:
return CGSize(width: 320.0, height: 480.0)
case .iPhone5:
return CGSize(width: 320.0, height: 568.0)
case .iPhone6:
return CGSize(width: 375.0, height: 667.0)
case .iPhone6Plus:
return CGSize(width: 414.0, height: 736.0)
case .iPhoneX:
return CGSize(width: 375.0, height: 812.0)
case .iPhoneXSMax:
return CGSize(width: 414.0, height: 896.0)
case .iPad:
return CGSize(width: 768.0, height: 1024.0)
case .iPadPro10Inch:
return CGSize(width: 834.0, height: 1112.0)
case .iPadPro11Inch:
return CGSize(width: 834.0, height: 1194.0)
case .iPadPro, .iPadPro3rdGen:
return CGSize(width: 1024.0, height: 1366.0)
case let .unknown(screenSize, _, _):
return screenSize
}
}
func safeInsets(inLandscape: Bool) -> UIEdgeInsets {
switch self {
case .iPhoneX, .iPhoneXSMax:
return inLandscape ? UIEdgeInsets(top: 0.0, left: 44.0, bottom: 0.0, right: 44.0) : UIEdgeInsets(top: 44.0, left: 0.0, bottom: 0.0, right: 0.0)
default:
return UIEdgeInsets.zero
}
}
func onScreenNavigationHeight(inLandscape: Bool, systemOnScreenNavigationHeight: CGFloat?) -> CGFloat? {
switch self {
case .iPhoneX, .iPhoneXSMax:
return inLandscape ? 21.0 : 34.0
case .iPadPro3rdGen, .iPadPro11Inch:
return 21.0
case .iPad, .iPadPro, .iPadPro10Inch:
if let systemOnScreenNavigationHeight = systemOnScreenNavigationHeight, !systemOnScreenNavigationHeight.isZero {
return 21.0
} else {
return nil
}
case let .unknown(_, _, onScreenNavigationHeight):
return onScreenNavigationHeight
default:
return nil
}
}
func statusBarHeight(for size: CGSize) -> CGFloat? {
let value = self.statusBarHeight
switch self {
case .iPad, .iPadPro10Inch, .iPadPro11Inch, .iPadPro, .iPadPro3rdGen:
return value
default:
if size.width < size.height {
return value
} else {
return nil
}
}
}
var statusBarHeight: CGFloat {
switch self {
case .iPhoneX, .iPhoneXSMax:
return 44.0
case .iPadPro11Inch, .iPadPro3rdGen:
return 24.0
case let .unknown(_, statusBarHeight, _):
return statusBarHeight
default:
return 20.0
}
}
public func keyboardHeight(inLandscape: Bool) -> CGFloat {
if inLandscape {
switch self {
case .iPhone4, .iPhone5:
return 162.0
case .iPhone6, .iPhone6Plus:
return 163.0
case .iPhoneX, .iPhoneXSMax:
return 172.0
case .iPad, .iPadPro10Inch:
return 348.0
case .iPadPro11Inch:
return 368.0
case .iPadPro:
return 421.0
case .iPadPro3rdGen:
return 441.0
case .unknown:
return 216.0
}
} else {
switch self {
case .iPhone4, .iPhone5, .iPhone6:
return 216.0
case .iPhone6Plus:
return 226.0
case .iPhoneX:
return 291.0
case .iPhoneXSMax:
return 302.0
case .iPad, .iPadPro10Inch:
return 263.0
case .iPadPro11Inch:
return 283.0
case .iPadPro:
return 328.0
case .iPadPro3rdGen:
return 348.0
case .unknown:
return 216.0
}
}
}
func predictiveInputHeight(inLandscape: Bool) -> CGFloat {
if inLandscape {
switch self {
case .iPhone4, .iPhone5, .iPhone6, .iPhone6Plus, .iPhoneX, .iPhoneXSMax:
return 37.0
case .iPad, .iPadPro10Inch, .iPadPro11Inch, .iPadPro, .iPadPro3rdGen:
return 50.0
case .unknown:
return 37.0
}
} else {
switch self {
case .iPhone4, .iPhone5:
return 37.0
case .iPhone6, .iPhoneX, .iPhoneXSMax:
return 44.0
case .iPhone6Plus:
return 45.0
case .iPad, .iPadPro10Inch, .iPadPro11Inch, .iPadPro, .iPadPro3rdGen:
return 50.0
case .unknown:
return 44.0
}
}
}
public func previewingContentSize(inLandscape: Bool) -> CGSize {
let screenSize = self.screenSize
if inLandscape {
switch self {
case .iPhone5:
return CGSize(width: screenSize.height, height: screenSize.width - 10.0)
case .iPhone6:
return CGSize(width: screenSize.height, height: screenSize.width - 22.0)
case .iPhone6Plus:
return CGSize(width: screenSize.height, height: screenSize.width - 22.0)
case .iPhoneX:
return CGSize(width: screenSize.height, height: screenSize.width + 48.0)
case .iPhoneXSMax:
return CGSize(width: screenSize.height, height: screenSize.width - 30.0)
default:
return CGSize(width: screenSize.height, height: screenSize.width - 10.0)
}
} else {
switch self {
case .iPhone5:
return CGSize(width: screenSize.width, height: screenSize.height - 50.0)
case .iPhone6:
return CGSize(width: screenSize.width, height: screenSize.height - 97.0)
case .iPhone6Plus:
return CGSize(width: screenSize.width, height: screenSize.height - 95.0)
case .iPhoneX:
return CGSize(width: screenSize.width, height: screenSize.height - 154.0)
case .iPhoneXSMax:
return CGSize(width: screenSize.width, height: screenSize.height - 84.0)
default:
return CGSize(width: screenSize.width, height: screenSize.height - 50.0)
}
}
}
public var hasTopNotch: Bool {
switch self {
case .iPhoneX, .iPhoneXSMax:
return true
default:
return false
}
}
}