Определение устройства iPad в iOS приложении на Swift
Правильный способ определения iPad в iOS
Основной и рекомендуемый Apple способ определить тип устройства — это использование свойства userInterfaceIdiom из класса UIDevice. Однако есть важные нюансы, которые нужно учитывать для надёжной работы.
1. Базовый подход с UIDevice
import UIKit
func isPad() -> Bool {
return UIDevice.current.userInterfaceIdiom == .pad
}
// Использование
if isPad() {
print("Устройство — iPad")
// Настраиваем интерфейс для iPad
} else {
print("Устройство — iPhone или iPod touch")
}
2. Учёт многозадачности на iPad (iPadOS 13+)
Начиная с iPadOS 13, iPad поддерживает режимы Split View и Slide Over. В этих режимах UIDevice.current.userInterfaceIdiom всё равно вернёт .pad, что корректно. Но если вам нужно определить, работает ли приложение в компактном режиме (как на iPhone), используйте traitCollection:
func isCompactHorizontal() -> Bool {
return UIScreen.main.traitCollection.horizontalSizeClass == .compact
}
// Проверка на iPad в компактном режиме
if UIDevice.current.userInterfaceIdiom == .pad && isCompactHorizontal() {
print("iPad в режиме Slide Over или Split View (компактный размер)")
}
3. Определение через traitCollection (для iOS 8+)
Более современный подход — использовать traitCollection.userInterfaceIdiom из текущей среды:
// В любом UIViewController
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
super.traitCollectionDidChange(previousTraitCollection)
if traitCollection.userInterfaceIdiom == .pad {
print("Текущая среда — iPad")
}
}
// Или глобально через UIApplication
func isPadUsingTraits() -> Bool {
guard let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene,
let window = windowScene.windows.first else {
return false
}
return window.traitCollection.userInterfaceIdiom == .pad
}
4. Проверка на iPhone-приложение, запущенное на iPad
Если ваше приложение не оптимизировано для iPad и запускается в масштабированном режиме (пиксель-ту-пиксель), UIDevice.current.userInterfaceIdiom всё равно вернёт .phone. Чтобы точно определить физическое устройство, используйте:
func isPhysicaliPad() -> Bool {
// Этот метод определяет именно аппаратное устройство
return UIDevice.current.model.hasPrefix("iPad") ||
UIDevice.current.localizedModel.hasPrefix("iPad")
}
// Более точный способ — через sysctl
func isiPadHardware() -> Bool {
var systemInfo = utsname()
uname(&systemInfo)
let machineMirror = Mirror(reflecting: systemInfo.machine)
let identifier = machineMirror.children.compactMap { child -> String? in
guard let value = child.value as? Int8, value != 0 else { return nil }
return String(UnicodeScalar(UInt8(value)))
}.joined()
return identifier.hasPrefix("iPad")
}
Рекомендация Apple
Apple советует использовать UIDevice.current.userInterfaceIdiom для большинства случаев, особенно если вы адаптируете интерфейс. Для определения физического устройства (например, для аналитики) используйте комбинацию UIDevice.current.model и UIDevice.current.userInterfaceIdiom.
Полный пример для production
enum DeviceType {
case iPad, iPhone, iPod, unknown
static var current: DeviceType {
let idiom = UIDevice.current.userInterfaceIdiom
let model = UIDevice.current.model
switch idiom {
case .pad:
return .iPad
case .phone:
if model.contains("iPod") {
return .iPod
}
return .iPhone
default:
return .unknown
}
}
}
// Использование
if DeviceType.current == .iPad {
// iPad-specific логика
}
<<Альтернативный подход: использование UIUserInterfaceIdiom через SwiftUI
Если вы используете SwiftUI (iOS 13+), можно определить устройство через среду окружения (Environment):
import SwiftUI
struct ContentView: View {
@Environment(\.horizontalSizeClass) var horizontalSizeClass
@Environment(\.verticalSizeClass) var verticalSizeClass
var body: some View {
if UIDevice.current.userInterfaceIdiom == .pad {
Text("Это iPad")
.font(.largeTitle)
} else {
Text("Это iPhone")
.font(.title)
}
}
}
В SwiftUI также можно использовать @Environment(\.userInterfaceIdiom) (доступно с iOS 14):
struct AdaptiveView: View {
@Environment(\.userInterfaceIdiom) var idiom
var body: some View {
switch idiom {
case .pad:
iPadLayout()
case .phone:
iPhoneLayout()
default:
Text("Другое устройство")
}
}
}
Дополнительный совет: избегайте проверок на конкретные модели
Старайтесь не проверять конкретные модели iPad (например, "iPad Pro 12.9"), так как это делает код хрупким. Вместо этого ориентируйтесь на размеры экрана и size classes. Для аналитики используйте UIDevice.current.model или библиотеки вроде DeviceKit.
Помните: лучшая практика — адаптировать интерфейс через size classes и Auto Layout, а не через жёсткие проверки типа устройства. Используйте проверку на iPad только когда это действительно необходимо (например, для работы с Apple Pencil или клавиатурой).