Skip to content
Permalink
Browse files

[Elevation] Add a UIColor category to support resolving color with el…

…evation. (#8085)

This PR provides two methods to allow users resolving color with elevation.

closes #8086.
  • Loading branch information...
wenyuzhang666 committed Jul 26, 2019
1 parent 657483e commit c3f8c6adeb4e3425d2997a291a3f616202f6c3c5
@@ -967,12 +967,15 @@ Pod::Spec.new do |mdc|
"components/#{component.base_name}/src/*.{h,m}",
"components/#{component.base_name}/src/private/*.{h,m}"
]
component.dependency "MaterialComponents/private/Color"
component.dependency "MaterialComponents/private/Math"

component.test_spec 'UnitTests' do |unit_tests|
unit_tests.source_files = [
"components/#{component.base_name}/tests/unit/*.{h,m,swift}",
"components/#{component.base_name}/tests/unit/supplemental/*.{h,m,swift}"
]
unit_tests.dependency "MaterialComponents/private/Color"
end
end

@@ -30,17 +30,23 @@ mdc_public_objc_library(
sdk_frameworks = [
"CoreGraphics",
],
deps = [
"//components/private/Color",
"//components/private/Math",
],
)

mdc_unit_test_objc_library(
name = "unit_test_sources",
testonly = 1,
sdk_frameworks = [
"UIKit",
"CoreGraphics",
],
visibility = ["//visibility:private"],
deps = [
":Elevation",
"//components/private/Color",
],
)

@@ -14,4 +14,5 @@

#import "MDCElevatable.h"
#import "MDCElevationOverriding.h"
#import "UIColor+MaterialElevation.h"
#import "UIView+MaterialElevationResponding.h"
@@ -0,0 +1,49 @@
// Copyright 2019-present the Material Components for iOS authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#import <CoreGraphics/CoreGraphics.h>
#import <UIKit/UIKit.h>

/**
Provides extension to UIColor for Material Elevation usage.
*/
@interface UIColor (MaterialElevation)

/**
Returns a color that takes the specified elevation value into account.
The color is the blended color of Surface and Elevation Overlay in
https://material.io/design/color/dark-theme.html#properties
Negative elevation is treated as 0.
Pattern-based UIColor is not supported.
@param elevation The @c mdc_absoluteElevation value to use when resolving the color.
*/
- (nonnull UIColor *)mdc_resolvedColorWithElevation:(CGFloat)elevation;

/**
Returns a color that takes the specified elevation value and traits into account.
When userInterfaceStyle is UIUserInterfaceStyleDark in traitCollection, elevation will be used
to resolve the color.
Negative elevation is treated as 0.
Pattern-based UIColor is not supported.
UIColor in UIExtendedGrayColorSpace will be resolved to UIExtendedSRGBColorSpace.
@param traitCollection The traits to use when resolving the color.
@param elevation The @c mdc_absoluteElevation to use when resolving the color.
*/
- (nonnull UIColor *)mdc_resolvedColorWithTraitCollection:
(nonnull UITraitCollection *)traitCollection
elevation:(CGFloat)elevation
API_AVAILABLE(ios(13.0));

@end
@@ -0,0 +1,62 @@
// Copyright 2019-present the Material Components for iOS authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#import "UIColor+MaterialElevation.h"

#import <CoreGraphics/CoreGraphics.h>

#import "MaterialMath.h"
#import "UIColor+MaterialBlending.h"

@implementation UIColor (MaterialElevation)

- (UIColor *)mdc_resolvedColorWithTraitCollection:(UITraitCollection *)traitCollection
elevation:(CGFloat)elevation {
#if defined(__IPHONE_13_0) && (__IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_13_0)
if (@available(iOS 13.0, *)) {
UIColor *resolvedColor = [self resolvedColorWithTraitCollection:traitCollection];
if (traitCollection.userInterfaceStyle == UIUserInterfaceStyleDark) {
return [resolvedColor mdc_resolvedColorWithElevation:elevation];
} else {
return resolvedColor;
}
}
#endif
[NSException raise:NSGenericException
format:@"%@ is only supported on iOS 13 and above", NSStringFromSelector(_cmd)];
return nil;
}

- (UIColor *)mdc_resolvedColorWithElevation:(CGFloat)elevation {
if (CGColorGetPattern(self.CGColor)) {
[NSException raise:NSGenericException
format:@"Pattern-based colors are not supported by %@", NSStringFromSelector(_cmd)];
}

UIColor *overlayColor = UIColor.whiteColor;
elevation = MAX(elevation, 0);
CGFloat alphaValue = 0;
if (!MDCCGFloatEqual(elevation, 0)) {
// A formula is used here to simulate the alpha percentage stated on
// https://material.io/design/color/dark-theme.html#properties
// AlphaValue = 4.5 * ln (elevationValue + 1) + 2
alphaValue = (CGFloat)4.5 * (CGFloat)log(elevation + 1) + 2;
}
// TODO (https://github.com/material-components/material-components-ios/issues/8096):
// Grayscale color should be returned if color space is UIExtendedGrayColorSpace.
return [UIColor mdc_blendColor:[overlayColor colorWithAlphaComponent:alphaValue * (CGFloat)0.01]
withBackgroundColor:self];
}

@end

0 comments on commit c3f8c6a

Please sign in to comment.
You can’t perform that action at this time.