如果需要的话可以使用私有API。在iOS 13.7、14.8、15.5和16.0上进行了测试,但不支持Mac Catalyst。
示例
UIVisualEffectView+Intensity.h
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface UIVisualEffectView (Intensity)
@property (nonatomic) CGFloat intensity;
@end
NS_ASSUME_NONNULL_END
UIVisualEffectView+Intensity.m
#import "UIVisualEffectView+Intensity.h"
#import <objc/message.h>
@interface UIVisualEffectView (Intensity)
@property (readonly) id backgroundHost;
@property (readonly) __kindof UIView *backdropView;
@end
@implementation UIVisualEffectView (Intensity)
- (id)backgroundHost {
id backgroundHost = ((id (*)(id, SEL))objc_msgSend)(self, NSSelectorFromString(@"_backgroundHost"));
return backgroundHost;
}
- (__kindof UIView * _Nullable)backdropView {
__kindof UIView *backdropView = ((__kindof UIView * (*)(id, SEL))objc_msgSend)(self.backgroundHost, NSSelectorFromString(@"contentView"));
return backdropView;
}
- (CGFloat)intensity {
__kindof UIView *backdropView = self.backdropView;
__kindof CALayer *backdropLayer = ((__kindof CALayer * (*)(id, SEL))objc_msgSend)(backdropView, NSSelectorFromString(@"backdropLayer"));
NSArray *filters = backdropLayer.filters;
id _Nullable __block gaussianBlur = nil;
[filters enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
if (![obj respondsToSelector:NSSelectorFromString(@"type")]) return;
NSString *type = ((NSString * (*)(id, SEL))objc_msgSend)(obj, NSSelectorFromString(@"type"));
if (![type isKindOfClass:[NSString class]]) return;
if ([type isEqualToString:@"gaussianBlur"]) {
gaussianBlur = obj;
*stop = YES;
}
}];
if (gaussianBlur == nil) return 0.0f;
NSNumber * _Nullable inputRadius = [gaussianBlur valueForKeyPath:@"inputRadius"];
if ((inputRadius == nil) || (![inputRadius isKindOfClass:[NSNumber class]])) return 0.0f;
return [inputRadius floatValue];
}
- (void)setIntensity:(CGFloat)intensity {
id descriptor = ((id (*)(id, SEL, id, BOOL))objc_msgSend)(self, NSSelectorFromString(@"_effectDescriptorForEffects:usage:"), @[self.effect], YES);
NSArray *filterEntries = ((NSArray * (*)(id, SEL))objc_msgSend)(descriptor, NSSelectorFromString(@"filterEntries"));
id _Nullable __block gaussianBlur = nil;
[filterEntries enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
NSString *filterType = ((NSString * (*)(id, SEL))objc_msgSend)(obj, NSSelectorFromString(@"filterType"));
if ([filterType isEqualToString:@"gaussianBlur"]) {
gaussianBlur = obj;
*stop = YES;
}
}];
if (gaussianBlur == nil) return;
NSMutableDictionary *requestedValues = [((NSDictionary * (*)(id, SEL))objc_msgSend)(gaussianBlur, NSSelectorFromString(@"requestedValues")) mutableCopy];
if (![requestedValues.allKeys containsObject:@"inputRadius"]) {
NSLog(@"Not supported effect.");
return;
}
requestedValues[@"inputRadius"] = [NSNumber numberWithFloat:intensity];
((void (*)(id, SEL, NSDictionary *))objc_msgSend)(gaussianBlur, NSSelectorFromString(@"setRequestedValues:"), requestedValues);
((void (*)(id, SEL, id))objc_msgSend)(self.backgroundHost, NSSelectorFromString(@"setCurrentEffectDescriptor:"), descriptor);
((void (*)(id, SEL))objc_msgSend)(self.backdropView, NSSelectorFromString(@"applyRequestedFilterEffects"));
}
@end
let firstBlurView: UIVisualEffectView = .init(effect: UIBlurEffect(style: .dark))
firstBlurView.intensity = 7
print(firstBlurView.intensity)