我的应用如何检测当前运行它的iPhone是否会使用简单的透明效果而不是模糊效果?

7
我的iPhone 4上运行iOS 7的应用程序使用具有自定义barTintColor的UITabBar。正如Apple文档中所述:https://developer.apple.com/library/ios/documentation/userexperience/conceptual/UIKitUICatalog/UITabBar.html 引用: 标签栏在iOS 7上默认为半透明。此外,所有选项卡栏都应用了系统模糊效果。这使得内容可以在栏下显示。
但是,在iPhone 4上,该系统模糊效果不可见,UITabBar在该设备上变为透明,如下所示:

我认为这可能是因为iPhone 4的GPU较弱,因此必须退回到透明度而不是半透明度。参考:http://arstechnica.com/apple/2013/09/new-lease-on-life-or-death-sentence-ios-7-on-the-iphone-4/ 一个简单的解决方法是有条件地使iPhone 4的UITabBar translucent。但是,我想知道是否可以在iOS GPU弱时检测到是否会退回到透明度?(从而使条件更加适当)

很抱歉,无法确定是否支持半透明效果,因为这是由GPU在运行时决定的。最好的方法是检查设备版本。 - Akshat Singhal
2个回答

6
这里是一些快速而简单的类别,用于检测设备是否支持模糊效果。希望能解决你的问题。
@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

你确定这个可行吗?我相信即使设备不支持模糊,工具栏也会将_UIBackdropView作为子视图。 - Scott Berrevoets
更新了代码,提供了一个类别,让您可以询问设备是否支持模糊。 - datinc
在 iPhone 4 上,工具栏的子视图为 _UIToolbarBackground、_UIBackdropView、UIView、UIImageView。而在 iPhone 5 上,子视图为 _UIToolbarBackground、_UIBackdropView、_UIBackdropEffectView。我们需要的是 _UIBackdropEffectView。 - datinc
值得注意的是,将 supportsBlur 包装在 dispatch_once 中是有意义的,以避免在每次调用时重新创建工具栏,并仅使用静态变量作为标志。 - pronebird
我同意当前实现不是线程安全的,但supportsBlur是静态的,因此toolBar变量只会被创建一次。 - datinc
然而,为了提供最好的代码,我添加了dispatch_once。 - datinc

1
据我所知,没有办法“基准测试”GPU以确定其是否过于弱小而无法显示半透明效果。即使您找到了这样的方法,与其检查当前设备是否为iPhone 4,这将是一种过度杀伤力的做法。问题在于,您无法检查边界或类似的东西,因为您仍然希望在iPhone 4S上显示该效果,因此无法排除任何不是iPhone 5的内容。 通常,我使用这个简单的类来识别用户设备。
#import "UIDeviceHardware.h"
#include <sys/types.h>
#include <sys/sysctl.h>

@implementation UIDeviceHardware

- (NSString *) platform{
    size_t size;
    sysctlbyname("hw.machine", NULL, &size, NULL, 0);
    char *machine = malloc(size);
    sysctlbyname("hw.machine", machine, &size, NULL, 0);
    NSString *platform = [NSString stringWithUTF8String:machine];
    free(machine);
    return platform;
}

- (NSString *) platformString{
    NSString *platform = [self platform];
    if ([platform isEqualToString:@"iPhone1,1"])    return @"iPhone 1G";
    if ([platform isEqualToString:@"iPhone1,2"])    return @"iPhone 3G";
    if ([platform isEqualToString:@"iPhone2,1"])    return @"iPhone 3GS";
    if ([platform isEqualToString:@"iPhone3,1"])    return @"iPhone 4";
    if ([platform isEqualToString:@"iPhone3,3"])    return @"Verizon iPhone 4";
    if ([platform isEqualToString:@"iPhone4,1"])    return @"iPhone 4S";
    if ([platform isEqualToString:@"iPhone5,1"])    return @"iPhone 5 (GSM)";
    if ([platform isEqualToString:@"iPhone5,2"])    return @"iPhone 5 (GSM+CDMA)";
    if ([platform isEqualToString:@"iPhone5,3"])    return @"iPhone 5c (GSM)";
    if ([platform isEqualToString:@"iPhone5,4"])    return @"iPhone 5c (Global)";
    if ([platform isEqualToString:@"iPhone6,1"])    return @"iPhone 5s (GSM)";
    if ([platform isEqualToString:@"iPhone6,2"])    return @"iPhone 5s (Global)";
    if ([platform isEqualToString:@"iPod1,1"])      return @"iPod Touch 1G";
    if ([platform isEqualToString:@"iPod2,1"])      return @"iPod Touch 2G";
    if ([platform isEqualToString:@"iPod3,1"])      return @"iPod Touch 3G";
    if ([platform isEqualToString:@"iPod4,1"])      return @"iPod Touch 4G";
    if ([platform isEqualToString:@"iPod5,1"])      return @"iPod Touch 5G";
    if ([platform isEqualToString:@"iPad1,1"])      return @"iPad";
    if ([platform isEqualToString:@"iPad2,1"])      return @"iPad 2 (WiFi)";
    if ([platform isEqualToString:@"iPad2,2"])      return @"iPad 2 (GSM)";
    if ([platform isEqualToString:@"iPad2,3"])      return @"iPad 2 (CDMA)";
    if ([platform isEqualToString:@"iPad2,4"])      return @"iPad 2 (WiFi)";
    if ([platform isEqualToString:@"iPad2,5"])      return @"iPad Mini (WiFi)";
    if ([platform isEqualToString:@"iPad2,6"])      return @"iPad Mini (GSM)";
    if ([platform isEqualToString:@"iPad2,7"])      return @"iPad Mini (GSM+CDMA)";
    if ([platform isEqualToString:@"iPad3,1"])      return @"iPad 3 (WiFi)";
    if ([platform isEqualToString:@"iPad3,2"])      return @"iPad 3 (GSM+CDMA)";
    if ([platform isEqualToString:@"iPad3,3"])      return @"iPad 3 (GSM)";
    if ([platform isEqualToString:@"iPad3,4"])      return @"iPad 4 (WiFi)";
    if ([platform isEqualToString:@"iPad3,5"])      return @"iPad 4 (GSM)";
    if ([platform isEqualToString:@"iPad3,6"])      return @"iPad 4 (GSM+CDMA)";
    if ([platform isEqualToString:@"iPad4,1"])      return @"iPad Air (WiFi)";
    if ([platform isEqualToString:@"iPad4,2"])      return @"iPad Air (GSM)";
    if ([platform isEqualToString:@"iPad4,4"])      return @"iPad Mini Retina (WiFi)";
    if ([platform isEqualToString:@"iPad4,5"])      return @"iPad Mini Retina (GSM)";
    if ([platform isEqualToString:@"i386"])         return @"Simulator";
    if ([platform isEqualToString:@"x86_64"])       return @"Simulator";
    return platform;
}

@end

1
那肯定是一种方法(正如我在问题中提到的),但我想要依赖于操作系统而不是设备。为了更好地解释,这样做更有意义,因为我的条件不是“如果设备是iPhone 4,则使视图不透明”,而是“如果iOS将要绘制它的透明而不是半透明,则使视图不透明”。我预期的是操作系统在这种情况下会设置一些宏。我希望苹果内部也会做类似的事情,否则整个系统就会变得脆弱。 - Ayush Goel
1
建议的代码归属:https://github.com/erica/uidevice-extension/ https://github.com/erica/uidevice-extension/blob/master/UIDevice-Hardware.m - Ayush Goel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接