Проверьте, поддерживает ли устройство размытие

Мое приложение использует 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
 }

Будьте осторожны, поскольку, хотя устройство может поддерживать размытие, пользователь может отключить расширенные визуальные эффекты в меню "Настройки", "Доступность".

Альтернативный метод

https://gist.github.com/conradev/8655650

Вот 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, которая объединяет следующие проверки доступности эффекта размытия:

  1. версия для iOS

  2. Тип устройства (спасибо Дэниелу Мартину)

  3. Частный метод UIDevice _graphicsQuality при сборке для симулятора. (Это сделано, потому что проверка типа устройства не работает в симуляторе - будет скомпилирована при сборке для архитектур рук)

  4. Параметр доступности "Уменьшить прозрачность"

Я сделал суть, содержащую категорию: https://gist.github.com/mortenbekditlevsen/5a0ee16b73a084ba404d

И небольшая рецензия на проблему в целом:

http://mojoapps.dk/?p=1

Примечание: при использовании 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. Похоже, что они все еще применяют оттенок цвета, так что, вероятно, в большинстве случаев это нормально Если вам действительно нужно изменить внешний вид, когда размытие не будет применено, я думаю, что имя устройства не является ужасным, поскольку в них конкретно указано, какие устройства не поддерживают размытие.

Другие вопросы по тегам