Проверьте, поддерживает ли устройство размытие
Мое приложение использует UIBlurEffect
Однако старые устройства (в частности, iPad 2 и 3, поддерживающие iOS 8) не поддерживают размытие.
Я хотел бы проверить, имеет ли пользовательское устройство поддержку размытия или нет. Как мне это сделать?
4 ответа
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
}
Будьте осторожны, поскольку, хотя устройство может поддерживать размытие, пользователь может отключить расширенные визуальные эффекты в меню "Настройки", "Доступность".
Альтернативный метод
Вот 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
И небольшая рецензия на проблему в целом:
Примечание: при использовании Gist, не забудьте подписаться на
UIAccessibilityReduceTransparencyStatusDidChangeNotificationуведомление для обновления пользовательского интерфейса при изменении настроек доступности.
Я надеюсь, что кто-то найдет это полезным.:-)
Вот несколько способов сделать это:
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. Похоже, что они все еще применяют оттенок цвета, так что, вероятно, в большинстве случаев это нормально Если вам действительно нужно изменить внешний вид, когда размытие не будет применено, я думаю, что имя устройства не является ужасным, поскольку в них конкретно указано, какие устройства не поддерживают размытие.