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

В моем приложении используется UIBlurEffect, однако более старые устройства (особенно iPad 2 и 3, поддерживающие iOS 8) не поддерживают размытие.

Я хотел бы проверить, поддерживает ли устройство пользователя размытие или нет. Как это сделать?


person Guilherme    schedule 10.01.2015    source источник


Ответы (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

person Daniel Martín    schedule 10.01.2015
comment
При использовании симулятора свойство 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
}
person Jeshurun    schedule 02.05.2015

Большое спасибо Даниэлю Мартину за отличный ответ. Я сделал категорию UIDevice, которая объединяет следующие проверки наличия эффекта размытия:

  1. iOS-версия

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

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

  4. Настройка специальных возможностей «Уменьшить прозрачность»

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

И небольшой репортаж о проблеме в целом:

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

Note: When using the gist, don't forget to subscribe to the

 UIAccessibilityReduceTransparencyStatusDidChangeNotification
notification to refresh the UI when the accessibility setting changes.

Я надеюсь, что кто-то найдет это полезным. :-)

person Morten Bek Ditlevsen    schedule 30.01.2015

Вот несколько способов сделать это:

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

person bjtitus    schedule 10.01.2015
comment
Это не сработает, потому что, поскольку устройство работает под управлением iOS 8, класс существует, но на старых устройствах вид размытия не будет отображаться так же, как на новых устройствах. - person Guilherme; 10.01.2015
comment
Извините, не заметил последнюю часть вопроса. Я считаю, что нет способа проверить это, не проверив имя устройства. - person bjtitus; 10.01.2015