В моем приложении используется UIBlurEffect
, однако более старые устройства (особенно iPad 2 и 3, поддерживающие iOS 8) не поддерживают размытие.
Я хотел бы проверить, поддерживает ли устройство пользователя размытие или нет. Как это сделать?
В моем приложении используется UIBlurEffect
, однако более старые устройства (особенно iPad 2 и 3, поддерживающие iOS 8) не поддерживают размытие.
Я хотел бы проверить, поддерживает ли устройство пользователя размытие или нет. Как это сделать?
UIDevice
имеет внутренний метод [UIDevice _graphicsQuality]
, который кажется многообещающим, но Apple, конечно же, отклонит ваше приложение. Создадим собственный метод:
Прежде всего, нам нужно знать точный тип устройства, над которым мы работаем:
#import <sys/utsname.h>
NSString* deviceName()
{
struct utsname systemInfo;
uname(&systemInfo);
return [NSString stringWithCString:systemInfo.machine
encoding:NSUTF8StringEncoding];
}
Например, это должно вернуть iPad2,1
для iPad 2. Вот обновленный список моделей iDevice: https://theiphonewiki.com/wiki/Models.
Итак, разделим наши модели устройств на две группы: с плохим качеством графики (и, соответственно, не поддерживающим размытие) и с отличным качеством графики. Согласно моему расследованию, это устройства, которые Apple считает «плохой» графикой (они могут измениться в будущем):
iPad iPad1,1 iPhone1,1 iPhone1,2 iPhone2,1 iPhone3,1 iPhone3,2 iPhone3,3 iPod1,1 iPod2,1 iPod2,2 iPod3,1 iPod4,1 iPad2,1 iPad2,2 iPad2,3 iPad2,4 iPad3 ,1 iPad3,2 iPad3,3
Итак, пишем следующий код:
NSSet *graphicsQuality = [NSSet setWithObjects:@"iPad",
@"iPad1,1",
@"iPhone1,1",
@"iPhone1,2",
@"iPhone2,1",
@"iPhone3,1",
@"iPhone3,2",
@"iPhone3,3",
@"iPod1,1",
@"iPod2,1",
@"iPod2,2",
@"iPod3,1",
@"iPod4,1",
@"iPad2,1",
@"iPad2,2",
@"iPad2,3",
@"iPad2,4",
@"iPad3,1",
@"iPad3,2",
@"iPad3,3",
nil];
if ([graphicsQuality containsObject:deviceName()]) {
// Device with poor graphics, blur not supported
} else {
// Blur supported
}
Будьте осторожны, поскольку даже если устройство поддерживает размытие, пользователь может отключить расширенные визуальные эффекты в меню «Настройки», «Специальные возможности».
Альтернативный метод
https://gist.github.com/conradev/8655650
systemInfo.machine
равно x86_64 (на моем Mac);
- person Tjalsma; 29.10.2015
Вот версия ответа Даниэля Мартина Swift. Часть кода была адаптирована из здесь:
func isBlurSupported() -> Bool {
var supported = Set<String>()
supported.insert("iPad")
supported.insert("iPad1,1")
supported.insert("iPhone1,1")
supported.insert("iPhone1,2")
supported.insert("iPhone2,1")
supported.insert("iPhone3,1")
supported.insert("iPhone3,2")
supported.insert("iPhone3,3")
supported.insert("iPod1,1")
supported.insert("iPod2,1")
supported.insert("iPod2,2")
supported.insert("iPod3,1")
supported.insert("iPod4,1")
supported.insert("iPad2,1")
supported.insert("iPad2,2")
supported.insert("iPad2,3")
supported.insert("iPad2,4")
supported.insert("iPad3,1")
supported.insert("iPad3,2")
supported.insert("iPad3,3")
return !supported.contains(hardwareString())
}
func hardwareString() -> String {
var name: [Int32] = [CTL_HW, HW_MACHINE]
var size: Int = 2
sysctl(&name, 2, nil, &size, &name, 0)
var hw_machine = [CChar](count: Int(size), repeatedValue: 0)
sysctl(&name, 2, &hw_machine, &size, &name, 0)
let hardware: String = String.fromCString(hw_machine)!
return hardware
}
Большое спасибо Даниэлю Мартину за отличный ответ. Я сделал категорию UIDevice, которая объединяет следующие проверки наличия эффекта размытия:
iOS-версия
Тип устройства (спасибо Дэниелу Мартину)
Приватный метод UIDevice _graphicsQuality при сборке для симулятора. (Это сделано, так как в симуляторе не работает проверка типа устройства - будет компилироваться при сборке для арм-архитектур)
Настройка специальных возможностей «Уменьшить прозрачность»
Я составил список, содержащий категорию: https://gist.github.com/mortenbekditlevsen/5a0ee16b73a084ba404d а>
И небольшой репортаж о проблеме в целом:
Note: When using the gist, don't forget to subscribe to the
UIAccessibilityReduceTransparencyStatusDidChangeNotificationnotification to refresh the UI when the accessibility setting changes.
Я надеюсь, что кто-то найдет это полезным. :-)
Вот несколько способов сделать это:
if objc_getClass("UIBlurEffect") != nil {
// UIBlurEffect exists
} else {
// UIBlurEffect doesn't exist
}
Или с доступом к классу blurEffect
if let blurEffect: AnyClass = NSClassFromString("UIBlurEffect") {
// UIBlurEffect exists
} else {
// UIBlurEffect doesn't exist
}
На самом деле здесь есть повторяющийся вопрос, хотя заголовок, вероятно, не облегчает его поиск: Как сделать слабое связывание в Swift?
-- Редактировать --
Неправильно понял вопрос. Кажется, нет никакого способа узнать это, кроме как проверить имя устройства:
Определить, правильно ли устройство отображает UIVisualEffectView?
Я бы полагался на любую резервную реализацию Apple. Похоже, они все еще применяют оттенок цвета, так что, вероятно, в большинстве случаев это нормально. Если вам действительно нужно изменить внешний вид, когда размытие не будет применяться, я думаю, что имя устройства не страшно, поскольку они специально указали, какие устройства не поддерживают размытие.