检查设备是否支持模糊
Check if device supports blur
我的应用程序使用 UIBlurEffect
,但是较旧的设备(特别是支持 iOS 8 的 iPad 2 和 3)不支持模糊处理。
我想检查用户的设备是否支持模糊。我该怎么做?
这里有几种方法可以做到这一点:
if objc_getClass("UIBlurEffect") != nil {
// UIBlurEffect exists
} else {
// UIBlurEffect doesn't exist
}
或者使用 blurEffect class
if let blurEffect: AnyClass = NSClassFromString("UIBlurEffect") {
// UIBlurEffect exists
} else {
// UIBlurEffect doesn't exist
}
这里实际上有一个重复的问题,虽然标题可能不容易找到:How do I do weak linking in Swift?
-- 编辑--
误解了问题。除了检查设备名称外,似乎无法找到它:
Detect if device properly displays UIVisualEffectView?
我会依赖 Apple 的后备实施。看起来他们仍然应用色调颜色,因此在大多数情况下这可能没问题。如果您真的必须在不应用模糊的情况下更改外观,我认为设备名称并不可怕,因为它们特别概述了哪些设备不支持模糊。
UIDevice
有一个内部方法 [UIDevice _graphicsQuality]
看起来很有前途,但你的应用程序当然会被 Apple 拒绝。让我们创建自己的方法:
首先,我们需要知道我们正在处理的确切设备类型:
#import <sys/utsname.h>
NSString* deviceName()
{
struct utsname systemInfo;
uname(&systemInfo);
return [NSString stringWithCString:systemInfo.machine
encoding:NSUTF8StringEncoding];
}
这应该 return iPad2,1
对于 iPad 2,例如。这是更新的 iDevice 型号列表:https://theiphonewiki.com/wiki/Models
因此,让我们将我们的设备模型分为两组:图形质量差的(因此不支持模糊)和图形质量好的。根据我的调查,这些是 Apple 考虑使用 "poor" 图形的设备(将来可能会更改):
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
}
请小心,因为即使设备可能支持模糊,用户也可能在“设置”、“辅助功能”中禁用了高级视觉效果。
替代方法
非常感谢 Daniel Martin 的精彩回答。
我制作了一个 UI 设备类别,其中结合了以下模糊效果可用性检查:
iOS版本
设备类型(感谢 Daniel Martin)
Private UI为模拟器构建时的设备方法 _graphicsQuality。
(这样做是因为设备类型检查在模拟器中不起作用——将在为 arm 架构构建时编译出来)
'Reduce Transparency' 辅助功能设置
我制作了一个包含类别的要点:
https://gist.github.com/mortenbekditlevsen/5a0ee16b73a084ba404d
还有一篇关于整个问题的小文章:
注意:使用 gist 时,不要忘记订阅
UIAccessibilityReduceTransparencyStatusDidChangeNotification
通知,以便在可访问性设置更改时刷新 UI。
我希望有人觉得这很有用。 :-)
这是 Daniel Martin 回答的 Swift 版本。部分代码改编自 here:
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
}
我的应用程序使用 UIBlurEffect
,但是较旧的设备(特别是支持 iOS 8 的 iPad 2 和 3)不支持模糊处理。
我想检查用户的设备是否支持模糊。我该怎么做?
这里有几种方法可以做到这一点:
if objc_getClass("UIBlurEffect") != nil {
// UIBlurEffect exists
} else {
// UIBlurEffect doesn't exist
}
或者使用 blurEffect class
if let blurEffect: AnyClass = NSClassFromString("UIBlurEffect") {
// UIBlurEffect exists
} else {
// UIBlurEffect doesn't exist
}
这里实际上有一个重复的问题,虽然标题可能不容易找到:How do I do weak linking in Swift?
-- 编辑--
误解了问题。除了检查设备名称外,似乎无法找到它:
Detect if device properly displays UIVisualEffectView?
我会依赖 Apple 的后备实施。看起来他们仍然应用色调颜色,因此在大多数情况下这可能没问题。如果您真的必须在不应用模糊的情况下更改外观,我认为设备名称并不可怕,因为它们特别概述了哪些设备不支持模糊。
UIDevice
有一个内部方法 [UIDevice _graphicsQuality]
看起来很有前途,但你的应用程序当然会被 Apple 拒绝。让我们创建自己的方法:
首先,我们需要知道我们正在处理的确切设备类型:
#import <sys/utsname.h>
NSString* deviceName()
{
struct utsname systemInfo;
uname(&systemInfo);
return [NSString stringWithCString:systemInfo.machine
encoding:NSUTF8StringEncoding];
}
这应该 return iPad2,1
对于 iPad 2,例如。这是更新的 iDevice 型号列表:https://theiphonewiki.com/wiki/Models
因此,让我们将我们的设备模型分为两组:图形质量差的(因此不支持模糊)和图形质量好的。根据我的调查,这些是 Apple 考虑使用 "poor" 图形的设备(将来可能会更改):
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
}
请小心,因为即使设备可能支持模糊,用户也可能在“设置”、“辅助功能”中禁用了高级视觉效果。
替代方法
非常感谢 Daniel Martin 的精彩回答。 我制作了一个 UI 设备类别,其中结合了以下模糊效果可用性检查:
iOS版本
设备类型(感谢 Daniel Martin)
Private UI为模拟器构建时的设备方法 _graphicsQuality。 (这样做是因为设备类型检查在模拟器中不起作用——将在为 arm 架构构建时编译出来)
'Reduce Transparency' 辅助功能设置
我制作了一个包含类别的要点: https://gist.github.com/mortenbekditlevsen/5a0ee16b73a084ba404d
还有一篇关于整个问题的小文章:
注意:使用 gist 时,不要忘记订阅
UIAccessibilityReduceTransparencyStatusDidChangeNotification通知,以便在可访问性设置更改时刷新 UI。
我希望有人觉得这很有用。 :-)
这是 Daniel Martin 回答的 Swift 版本。部分代码改编自 here:
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
}