Merge pull request #330 from adkenyon/a11y-fallback-for-reduce-transparency
Fallback background color for A11y reduce transparency
This commit is contained in:
commit
fa4711bf4d
|
@ -95,6 +95,8 @@ import { BlurView, VibrancyView } from "@react-native-community/blur";
|
||||||
- `ultraThinMaterialLight` - An adaptable blur effect that creates the appearance of an ultra-thin material.
|
- `ultraThinMaterialLight` - An adaptable blur effect that creates the appearance of an ultra-thin material.
|
||||||
- `blurAmount` (Default: 10, Number)
|
- `blurAmount` (Default: 10, Number)
|
||||||
- `0-100` - Adjusts blur intensity
|
- `0-100` - Adjusts blur intensity
|
||||||
|
- `reducedTransparencyFallbackColor` (Color) (iOS only)
|
||||||
|
- `black, white, #rrggbb, etc` - background color to use if accessibility setting ReduceTransparency is enabled
|
||||||
|
|
||||||
> Note: The maximum `blurAmount` on Android is 32, so higher values will be clamped to 32.
|
> Note: The maximum `blurAmount` on Android is 32, so higher values will be clamped to 32.
|
||||||
|
|
||||||
|
@ -122,6 +124,7 @@ export default class Menu extends Component {
|
||||||
viewRef={this.state.viewRef}
|
viewRef={this.state.viewRef}
|
||||||
blurType="light"
|
blurType="light"
|
||||||
blurAmount={10}
|
blurAmount={10}
|
||||||
|
reducedTransparencyFallbackColor="white"
|
||||||
/>
|
/>
|
||||||
<Text>I'm the non blurred text because I got rendered on top of the BlurView</Text>
|
<Text>I'm the non blurred text because I got rendered on top of the BlurView</Text>
|
||||||
</View>
|
</View>
|
||||||
|
@ -146,9 +149,11 @@ const styles = StyleSheet.create({
|
||||||
|
|
||||||
In this example, the `Image` component will be blurred, because the `BlurView` in positioned on top. But the `Text` will stay unblurred.
|
In this example, the `Image` component will be blurred, because the `BlurView` in positioned on top. But the `Text` will stay unblurred.
|
||||||
|
|
||||||
|
If the [accessibility setting `Reduce Transparency`](https://support.apple.com/guide/iphone/display-settings-iph3e2e1fb0/ios) is enabled the `BlurView` will use `reducedTransparencyFallbackColor` as it's background color rather than blurring. If no `reducedTransparencyFallbackColor` is provided, the`BlurView`will use the default fallback color (white, black, or grey depending on `blurType`)
|
||||||
|
|
||||||
### VibrancyView
|
### VibrancyView
|
||||||
|
|
||||||
**Uses the same properties as `BlurView` (`blurType` and `blurAmount`).**
|
**Uses the same properties as `BlurView` (`blurType`, `blurAmount`, and `reducedTransparencyFallbackColor`).**
|
||||||
|
|
||||||
> The vibrancy effect lets the content underneath a blurred view show through more vibrantly
|
> The vibrancy effect lets the content underneath a blurred view show through more vibrantly
|
||||||
|
|
||||||
|
|
|
@ -60,6 +60,7 @@ export default class Basic extends Component {
|
||||||
<BlurView
|
<BlurView
|
||||||
blurType={this.state.blurBlurType}
|
blurType={this.state.blurBlurType}
|
||||||
blurAmount={100}
|
blurAmount={100}
|
||||||
|
reducedTransparencyFallbackColor={'pink'}
|
||||||
style={[styles.blurView]}>
|
style={[styles.blurView]}>
|
||||||
<Text style={[styles.text, { color: tintColor }]}>
|
<Text style={[styles.text, { color: tintColor }]}>
|
||||||
Blur component ({platform})
|
Blur component ({platform})
|
||||||
|
@ -84,6 +85,7 @@ export default class Basic extends Component {
|
||||||
<VibrancyView
|
<VibrancyView
|
||||||
blurType={this.state.vibrancyBlurType}
|
blurType={this.state.vibrancyBlurType}
|
||||||
blurAmount={10}
|
blurAmount={10}
|
||||||
|
reducedTransparencyFallbackColor={'pink'}
|
||||||
style={[styles.container, styles.blurContainer]}>
|
style={[styles.container, styles.blurContainer]}>
|
||||||
|
|
||||||
<Text style={styles.text}>
|
<Text style={styles.text}>
|
||||||
|
|
|
@ -2,7 +2,7 @@ import * as React from "react";
|
||||||
import { StyleProp, ViewStyle } from "react-native";
|
import { StyleProp, ViewStyle } from "react-native";
|
||||||
|
|
||||||
export interface BlurViewProperties {
|
export interface BlurViewProperties {
|
||||||
blurType:
|
blurType?:
|
||||||
| "xlight"
|
| "xlight"
|
||||||
| "light"
|
| "light"
|
||||||
| "dark"
|
| "dark"
|
||||||
|
@ -28,6 +28,7 @@ export interface BlurViewProperties {
|
||||||
// tvOS only
|
// tvOS only
|
||||||
| "extraDark"
|
| "extraDark"
|
||||||
blurAmount?: number // 0 - 100
|
blurAmount?: number // 0 - 100
|
||||||
|
reducedTransparencyFallbackColor?: string
|
||||||
style?: StyleProp<ViewStyle>
|
style?: StyleProp<ViewStyle>
|
||||||
blurRadius?: number
|
blurRadius?: number
|
||||||
downsampleFactor?: number
|
downsampleFactor?: number
|
||||||
|
|
|
@ -33,8 +33,9 @@ export type BlurType =
|
||||||
| 'extraDark';
|
| 'extraDark';
|
||||||
|
|
||||||
export type BlurViewProps = {
|
export type BlurViewProps = {
|
||||||
blurType: BlurType,
|
blurType?: BlurType,
|
||||||
blurAmount: number, // 0 - 100
|
blurAmount?: number, // 0 - 100,
|
||||||
|
reducedTransparencyFallbackColor?: String,
|
||||||
style?: ?ViewStyleProp,
|
style?: ?ViewStyleProp,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -3,11 +3,15 @@
|
||||||
|
|
||||||
@interface BlurView : UIView
|
@interface BlurView : UIView
|
||||||
|
|
||||||
@property (nonatomic, copy) NSString *blurType;
|
@property (nonatomic, copy, nullable) NSString *blurType;
|
||||||
@property (nonatomic, copy) NSNumber *blurAmount;
|
@property (nonatomic, copy, nullable) NSNumber *blurAmount;
|
||||||
|
@property (nonatomic, copy, nullable) UIColor *reducedTransparencyFallbackColor;
|
||||||
|
|
||||||
@property (nonatomic, strong) BlurEffectWithAmount *blurEffect;
|
@property (nonatomic, strong, nullable) BlurEffectWithAmount *blurEffect;
|
||||||
@property (nonatomic, strong) UIVisualEffectView *blurEffectView;
|
@property (nonatomic, strong, nullable) UIVisualEffectView *blurEffectView;
|
||||||
|
@property (nonatomic, strong, nullable) UIView *reducedTransparencyFallbackView;
|
||||||
|
|
||||||
- (void)updateBlurEffect;
|
- (void)updateBlurEffect;
|
||||||
|
- (void)updateFallbackView;
|
||||||
|
- (BOOL)useReduceTransparencyFallback;
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -7,28 +7,52 @@
|
||||||
|
|
||||||
@implementation BlurView
|
@implementation BlurView
|
||||||
|
|
||||||
- (instancetype)initWithFrame:(CGRect)frame {
|
- (instancetype)init
|
||||||
if (self = [super initWithFrame:frame]) {
|
{
|
||||||
self.blurEffectView = [[UIVisualEffectView alloc] init];
|
if (self = [super init]) {
|
||||||
self.blurEffectView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
|
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||||
self.blurEffectView.frame = frame;
|
selector:@selector(reduceTransparencyStatusDidChange:)
|
||||||
|
name:UIAccessibilityReduceTransparencyStatusDidChangeNotification
|
||||||
|
object:nil];
|
||||||
|
}
|
||||||
|
|
||||||
self.blurAmount = @10;
|
return self;
|
||||||
self.blurType = @"dark";
|
}
|
||||||
[self updateBlurEffect];
|
|
||||||
|
|
||||||
self.clipsToBounds = true;
|
- (instancetype)initWithFrame:(CGRect)frame
|
||||||
|
{
|
||||||
|
if (self = [super initWithFrame:frame]) {
|
||||||
|
self.blurEffectView = [[UIVisualEffectView alloc] init];
|
||||||
|
self.blurEffectView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
|
||||||
|
self.blurEffectView.frame = frame;
|
||||||
|
|
||||||
[self addSubview:self.blurEffectView];
|
self.reducedTransparencyFallbackView = [[UIView alloc] init];
|
||||||
}
|
self.reducedTransparencyFallbackView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
|
||||||
|
self.reducedTransparencyFallbackView.frame = frame;
|
||||||
|
|
||||||
return self;
|
self.blurAmount = @10;
|
||||||
|
self.blurType = @"dark";
|
||||||
|
[self updateBlurEffect];
|
||||||
|
[self updateFallbackView];
|
||||||
|
|
||||||
|
self.clipsToBounds = true;
|
||||||
|
|
||||||
|
[self addSubview:self.blurEffectView];
|
||||||
|
}
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)dealloc
|
||||||
|
{
|
||||||
|
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)layoutSubviews
|
- (void)layoutSubviews
|
||||||
{
|
{
|
||||||
[super layoutSubviews];
|
[super layoutSubviews];
|
||||||
self.blurEffectView.frame = self.bounds;
|
self.blurEffectView.frame = self.bounds;
|
||||||
|
self.reducedTransparencyFallbackView.frame = self.bounds;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)setBlurType:(NSString *)blurType
|
- (void)setBlurType:(NSString *)blurType
|
||||||
|
@ -47,6 +71,13 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)setReducedTransparencyFallbackColor:(nullable UIColor *)reducedTransparencyFallbackColor
|
||||||
|
{
|
||||||
|
if (reducedTransparencyFallbackColor && ![self.reducedTransparencyFallbackColor isEqual:reducedTransparencyFallbackColor]) {
|
||||||
|
_reducedTransparencyFallbackColor = reducedTransparencyFallbackColor;
|
||||||
|
[self updateFallbackView];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
- (UIBlurEffectStyle)blurEffectStyle
|
- (UIBlurEffectStyle)blurEffectStyle
|
||||||
{
|
{
|
||||||
|
@ -89,6 +120,11 @@
|
||||||
return UIBlurEffectStyleDark;
|
return UIBlurEffectStyleDark;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (BOOL)useReduceTransparencyFallback
|
||||||
|
{
|
||||||
|
return UIAccessibilityIsReduceTransparencyEnabled() == YES && self.reducedTransparencyFallbackColor != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
- (void)updateBlurEffect
|
- (void)updateBlurEffect
|
||||||
{
|
{
|
||||||
UIBlurEffectStyle style = [self blurEffectStyle];
|
UIBlurEffectStyle style = [self blurEffectStyle];
|
||||||
|
@ -96,4 +132,32 @@
|
||||||
self.blurEffectView.effect = self.blurEffect;
|
self.blurEffectView.effect = self.blurEffect;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)updateFallbackView
|
||||||
|
{
|
||||||
|
if ([self useReduceTransparencyFallback]) {
|
||||||
|
if (![self.subviews containsObject:self.reducedTransparencyFallbackView]) {
|
||||||
|
[self insertSubview:self.reducedTransparencyFallbackView atIndex:0];
|
||||||
|
}
|
||||||
|
|
||||||
|
if ([self.subviews containsObject:self.blurEffectView]) {
|
||||||
|
[self.blurEffectView removeFromSuperview];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if ([self.subviews containsObject:self.reducedTransparencyFallbackView]) {
|
||||||
|
[self.reducedTransparencyFallbackView removeFromSuperview];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (![self.subviews containsObject:self.blurEffectView]) {
|
||||||
|
[self insertSubview:self.blurEffectView atIndex:0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self.reducedTransparencyFallbackView.backgroundColor = self.reducedTransparencyFallbackColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)reduceTransparencyStatusDidChange:(__unused NSNotification *)notification
|
||||||
|
{
|
||||||
|
[self updateFallbackView];
|
||||||
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -12,5 +12,6 @@ RCT_EXPORT_MODULE();
|
||||||
|
|
||||||
RCT_EXPORT_VIEW_PROPERTY(blurType, NSString);
|
RCT_EXPORT_VIEW_PROPERTY(blurType, NSString);
|
||||||
RCT_EXPORT_VIEW_PROPERTY(blurAmount, NSNumber);
|
RCT_EXPORT_VIEW_PROPERTY(blurAmount, NSNumber);
|
||||||
|
RCT_EXPORT_VIEW_PROPERTY(reducedTransparencyFallbackColor, UIColor);
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -30,7 +30,11 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)insertReactSubview:(id<RCTComponent>)subview atIndex:(NSInteger)atIndex {
|
- (void)insertReactSubview:(id<RCTComponent>)subview atIndex:(NSInteger)atIndex {
|
||||||
|
if ([self useReduceTransparencyFallback]) {
|
||||||
|
[self addSubview:(UIView*)subview];
|
||||||
|
} else {
|
||||||
[self.vibrancyEffectView.contentView addSubview:(UIView*)subview];
|
[self.vibrancyEffectView.contentView addSubview:(UIView*)subview];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)updateBlurEffect
|
- (void)updateBlurEffect
|
||||||
|
@ -45,4 +49,24 @@
|
||||||
self.vibrancyEffectView.effect = self.vibrancyEffect;
|
self.vibrancyEffectView.effect = self.vibrancyEffect;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)updateFallbackView
|
||||||
|
{
|
||||||
|
[super updateFallbackView];
|
||||||
|
|
||||||
|
if ([self useReduceTransparencyFallback]) {
|
||||||
|
for (UIView *subview in self.blurEffectView.contentView.subviews) {
|
||||||
|
[subview removeFromSuperview];
|
||||||
|
[self addSubview:subview];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (UIView *subview in self.subviews) {
|
||||||
|
if (subview == self.blurEffectView) continue;
|
||||||
|
if (subview == self.reducedTransparencyFallbackView) continue;
|
||||||
|
|
||||||
|
[subview removeFromSuperview];
|
||||||
|
[self.blurEffectView.contentView addSubview:subview];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -12,5 +12,6 @@ RCT_EXPORT_MODULE();
|
||||||
|
|
||||||
RCT_EXPORT_VIEW_PROPERTY(blurType, NSString);
|
RCT_EXPORT_VIEW_PROPERTY(blurType, NSString);
|
||||||
RCT_EXPORT_VIEW_PROPERTY(blurAmount, NSNumber);
|
RCT_EXPORT_VIEW_PROPERTY(blurAmount, NSNumber);
|
||||||
|
RCT_EXPORT_VIEW_PROPERTY(reducedTransparencyFallbackColor, UIColor);
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
Loading…
Reference in New Issue