Skip to content

Commit

Permalink
[Shadows] Code improvements for the new Shadow component.
Browse files Browse the repository at this point in the history
PiperOrigin-RevId: 367871950
  • Loading branch information
yarneo authored and material-automation committed Apr 11, 2021
1 parent caaed1b commit e2f4fd3
Show file tree
Hide file tree
Showing 11 changed files with 439 additions and 281 deletions.
17 changes: 12 additions & 5 deletions components/Shadow/examples/ShadowTypicalUseExample.swift
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,15 @@ final class ShadowedView: UIView {

override func layoutSubviews() {
super.layoutSubviews()
MDCConfigureShadow(for: self, color: MDCShadowColor(), elevation: 2)
MDCConfigureShadow(
for: self, shadow: MDCShadowForElevation(1, MDCShadowsCollectionDefault()),
color: MDCShadowColor())
}
}

/// Typical use-case for a shaped view with Material Shadows.
final class ShapedView: UIView {
let shapeLayer = CAShapeLayer()
let shadow = MDCShadowForElevation(2)

override init(frame: CGRect) {
super.init(frame: frame)
Expand All @@ -61,14 +62,17 @@ final class ShapedView: UIView {
super.layoutSubviews()
guard let path = polygonPath(bounds: self.bounds, numSides: 3, numPoints: 3) else { return }
shapeLayer.path = path
MDCConfigureShadow(for: self, color: MDCShadowColor(), shadow: shadow, path: path)

MDCConfigureShadow(
for: self, shadow: MDCShadowForElevation(1, MDCShadowsCollectionDefault()),
color: MDCShadowColor(),
path: path)
}
}

/// More complex use-case for a view with a custom shape which animates.
final class AnimatedShapedView: UIView {
let shapeLayer = CAShapeLayer()
let shadow = MDCShadowForElevation(2)
let firstNumSides = 3
let lastNumSides = 12
let animationStepDuration: CFTimeInterval = 0.6
Expand Down Expand Up @@ -104,7 +108,10 @@ final class AnimatedShapedView: UIView {
bounds: bounds, numSides: firstNumSides, numPoints: lastNumSides)
else { return }
shapeLayer.path = startPath
MDCConfigureShadow(for: self, color: MDCShadowColor(), shadow: shadow, path: startPath)
MDCConfigureShadow(
for: self, shadow: MDCShadowForElevation(1, MDCShadowsCollectionDefault()),
color: MDCShadowColor(),
path: startPath)

var polygonPaths = (firstNumSides...lastNumSides).map {
polygonPath(bounds: bounds, numSides: $0, numPoints: lastNumSides)
Expand Down
25 changes: 10 additions & 15 deletions components/Shadow/src/MDCShadow.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,14 @@
#import <UIKit/UIKit.h>

/**
Immutable value type holding shadow metrics to apply to a view's layer. Use
`MDCShadowForElevation()` or `MDCShadowBuilder` to create this object.
An immutable shadow object that consists of shadow properties (opacity, radius, offset).
To generate a shadow instance, please use the MDCShadowBuilder APIs.
*/
__attribute__((objc_subclassing_restricted)) @interface MDCShadow : NSObject

- (nonnull instancetype)init NS_UNAVAILABLE;

/** CALayer.shadowOpacity */
@property(nonatomic, readonly) CGFloat opacity;

Expand All @@ -29,8 +32,6 @@ __attribute__((objc_subclassing_restricted)) @interface MDCShadow : NSObject
/** CALayer.shadowOffset */
@property(nonatomic, readonly) CGSize offset;

- (nonnull instancetype)init NS_UNAVAILABLE;

@end

/**
Expand All @@ -50,15 +51,9 @@ __attribute__((objc_subclassing_restricted)) @interface MDCShadowBuilder : NSObj
/** Returns an immutable value type containing a snapshot of the values in this object. */
- (nonnull MDCShadow *)build;

@end

/**
Default color for a Material shadow. On iOS >= 13, this is a dynamic color.
*/
FOUNDATION_EXTERN UIColor *_Nonnull MDCShadowColor(void);
/** Returns a builder with the provided opacity, radius, and offset properties. */
+ (nonnull MDCShadowBuilder *)builderWithOpacity:(CGFloat)opacity
radius:(CGFloat)radius
offset:(CGSize)offset;

/**
Returns an `MDCShadow` representing the Material shadow metrics for the given elevation (in
points).
*/
FOUNDATION_EXTERN MDCShadow *_Nonnull MDCShadowForElevation(CGFloat elevation);
@end
75 changes: 9 additions & 66 deletions components/Shadow/src/MDCShadow.m
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,6 @@

#import "MDCShadow.h"

#import "MaterialAvailability.h"
#import "MDCShadow+Internal.h"

@implementation MDCShadow

- (instancetype)initWithOpacity:(CGFloat)opacity radius:(CGFloat)radius offset:(CGSize)offset {
Expand Down Expand Up @@ -59,68 +56,14 @@ - (MDCShadow *)build {
return [[MDCShadow alloc] initWithOpacity:self.opacity radius:self.radius offset:self.offset];
}

@end

static UIColor *LightStyleShadowColor(void) {
static UIColor *lightStyleShadowColor;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
lightStyleShadowColor = [UIColor colorWithRed:0.235 green:0.251 blue:0.263 alpha:1];
});
return lightStyleShadowColor;
}

UIColor *MDCShadowColor(void) {
#if MDC_AVAILABLE_SDK_IOS(13_0)
if (@available(iOS 13.0, *)) {
return [UIColor colorWithDynamicProvider:^(UITraitCollection *traitCollection) {
switch (traitCollection.userInterfaceStyle) {
case UIUserInterfaceStyleUnspecified:
__attribute__((fallthrough));
case UIUserInterfaceStyleLight:
return LightStyleShadowColor();
case UIUserInterfaceStyleDark:
return UIColor.blackColor;
}
__builtin_unreachable();
}];
}
#endif // MDC_AVAILABLE_SDK_IOS(13_0)
return LightStyleShadowColor();
+ (MDCShadowBuilder *)builderWithOpacity:(CGFloat)opacity
radius:(CGFloat)radius
offset:(CGSize)offset {
MDCShadowBuilder *builder = [[MDCShadowBuilder alloc] init];
builder.opacity = opacity;
builder.radius = radius;
builder.offset = offset;
return builder;
}

static int ShadowElevationToLevel(CGFloat elevation) {
if (elevation < 1) {
return 0;
}
if (elevation < 3) {
return 1;
}
if (elevation < 6) {
return 2;
}
if (elevation < 8) {
return 3;
}
if (elevation < 12) {
return 4;
}
return 5;
}

MDCShadow *MDCShadowForElevation(CGFloat elevation) {
static NSArray *shadowLevels;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
shadowLevels = @[
[[MDCShadow alloc] initWithOpacity:0 radius:0 offset:CGSizeMake(0, 0)],
[[MDCShadow alloc] initWithOpacity:0.43 radius:2.5 offset:CGSizeMake(0, 1)],
[[MDCShadow alloc] initWithOpacity:0.4 radius:3.25 offset:CGSizeMake(0, 1.25)],
[[MDCShadow alloc] initWithOpacity:0.34 radius:4.75 offset:CGSizeMake(0, 2.25)],
[[MDCShadow alloc] initWithOpacity:0.42 radius:6 offset:CGSizeMake(0, 3)],
[[MDCShadow alloc] initWithOpacity:0.4 radius:7.25 offset:CGSizeMake(0, 5)],
];
});
int shadowLevel = ShadowElevationToLevel(elevation);
return shadowLevels[shadowLevel];
}
@end
87 changes: 0 additions & 87 deletions components/Shadow/src/MDCShadowConfiguring.h

This file was deleted.

52 changes: 0 additions & 52 deletions components/Shadow/src/MDCShadowConfiguring.m

This file was deleted.

Loading

0 comments on commit e2f4fd3

Please sign in to comment.