Check If Device Supports Blur

Check if device supports blur

UIDevice has an internal method [UIDevice _graphicsQuality] that seems promising, but of course your app will be rejected by Apple. Let's create our own method:

First of all, we need to know the exact device type we're working on:

#import <sys/utsname.h>

NSString* deviceName()
{
struct utsname systemInfo;
uname(&systemInfo);

return [NSString stringWithCString:systemInfo.machine
encoding:NSUTF8StringEncoding];
}

This should return iPad2,1 for iPad 2, for example. Here's an updated list of iDevice models: https://theiphonewiki.com/wiki/Models

So, let's classify our device models in two groups: those that have poor graphics quality (and thus don't support blur), and those with great graphics quality. According to my investigation, these are the devices that Apple considers with "poor" graphics (these may change in the future):

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

So we write the following code:

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
}

Be careful because even though the device may support blur, the user may have disabled advanced visual effects from Settings, Accessibility.

Alternative method

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

Detect if device properly displays UIVisualEffectView?

Check this WWDC session: http://asciiwwdc.com/2014/sessions/419

So, and to reiterate on what devices we don't blur and that we only do the tinting on the iPad 2 and iPad 3rd generation, we just apply the tint and we skip the blur steps.

[...]

On iPad 4th generation, iPad Air, iPad Mini, iPad Mini with retina display, iPhones and the iPod touch we do both the blur and the tinting.

I guess you have to resort to checking for the machine name:

#import <sys/utsname.h>
...

struct utsname systemInfo;
uname(&systemInfo);

NSString *deviceName = [NSString stringWithCString:systemInfo.machine encoding:NSUTF8StringEncoding];
...

How can I detect if the iPhone my app is on, is going to use a simple transparent effect instead of the blur effect?

Here are some quick and dirty categories that detects if the device supports blur. Hope it solves your problem

@interface UIToolbar (support)
@property (nonatomic, readonly) BOOL supportsBlur;
@end

@implementation UIToolbar (support)
-(BOOL) supportsBlur{
return [self _supportsBlur:self];
}

-(BOOL)_supportsBlur:(UIView*) view{
if ([view isKindOfClass:NSClassFromString(@"_UIBackdropEffectView")]){
return YES;
}

for (UIView* subview in view.subviews){
if ([self _supportsBlur:subview]){
return YES;
}
}
return NO;
}
@end

// Use this category to detect if the device supports blur
@interface UIDevice (support)
@property (nonatomic, readonly) BOOL supportsBlur;
@end

@implementation UIDevice (support)
-(BOOL) supportsBlur{
static BOOL supportsBlur = NO;
static dispatch_once_t onceToken = 0;
dispatch_once(&onceToken, ^{
UIToolbar* toolBar = [[UIToolbar alloc] init];
[toolBar layoutSubviews];
supportsBlur = toolBar.supportsBlur;
});
return supportsBlur;
}
@end

Detect if device properly displays UIVisualEffectView?

Check this WWDC session: http://asciiwwdc.com/2014/sessions/419

So, and to reiterate on what devices we don't blur and that we only do the tinting on the iPad 2 and iPad 3rd generation, we just apply the tint and we skip the blur steps.

[...]

On iPad 4th generation, iPad Air, iPad Mini, iPad Mini with retina display, iPhones and the iPod touch we do both the blur and the tinting.

I guess you have to resort to checking for the machine name:

#import <sys/utsname.h>
...

struct utsname systemInfo;
uname(&systemInfo);

NSString *deviceName = [NSString stringWithCString:systemInfo.machine encoding:NSUTF8StringEncoding];
...

How can I feature-detect CSS filters?

You can now use CSS' build-in @support to conditionally apply styles. Note that the browser support for @support is good but not perfect. This is a nice article explaining how it works with several examples: https://iamsteve.me/blog/entry/feature-detection-with-css

For instance, you can do something like this (see it live):

@supports (filter: grayscale(1)) or (-webkit-filter: grayscale(1)) {
h3 {
-webkit-filter: grayscale(1);
filter: grayscale(1);
}
}

@supports not (filter: grayscale(1)) and not not (-webkit-filter: grayscale(1)) {
h3 {
color: #808080;
}
}

Feature detecting support for svg filters

You could probably also check the enums available on the interfaces, e.g:

var supportsfilter = typeof SVGFEColorMatrixElement !== undefined && 
SVGFEColorMatrixElement.SVG_FECOLORMATRIX_TYPE_SATURATE==2;

That way you won't have to construct new elements, as in https://stackoverflow.com/a/9767059/109374. I've not tested to see whether this works as expected in Safari.

Update:
Patch submitted to modernizr: https://github.com/Modernizr/Modernizr/pull/531

CSS: Workaround to backdrop-filter?

As of Chrome M76, backdrop-filter is now shipped, unprefixed, and without a needed flag.

https://web.dev/backdrop-filter/

NOTE: (since this answer keeps getting downvoted because Mozilla hasn’t yet shipped it): this feature is available in Safari, Chrome, and Edge, but not yet in Firefox. Mozilla is planning to ship it very soon, but hasn’t yet. So this answer doesn’t contain a “workaround” but simply more information about which browsers require a workaround. Which still seems like useful information.



Related Topics



Leave a reply



Submit