blob: b49849f9d360431aeda421f731aefb6c3f1432f3 [file] [log] [blame] [edit]
// Copyright 2015-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 "MDCThumbView.h"
#import "MaterialShadowElevations.h"
#import "MaterialShapeLibrary.h"
#import "MaterialShapes.h"
@interface MDCThumbView ()
@property(nonatomic, strong) UIImageView *iconView;
// The shape generator used to define the shape of the thumb view.
@property(nullable, nonatomic, strong) MDCRectangleShapeGenerator *shapeGenerator;
@property(nonatomic, readonly, strong) MDCShapedShadowLayer *layer;
@end
@implementation MDCThumbView
@dynamic layer;
+ (Class)layerClass {
return [MDCShapedShadowLayer class];
}
- (instancetype)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
// TODO: Remove once MDCShadowLayer is rasterized by default.
self.layer.shouldRasterize = YES;
if (@available(iOS 13.0, *)) {
self.layer.rasterizationScale = UITraitCollection.currentTraitCollection.displayScale;
} else {
#if !TARGET_OS_VISION
self.layer.rasterizationScale = UIScreen.mainScreen.scale;
#endif
}
_shadowColor = UIColor.blackColor;
_shapeGenerator = [[MDCRectangleShapeGenerator alloc] init];
self.layer.shadowColor = _shadowColor.CGColor;
self.layer.shapeGenerator = _shapeGenerator;
}
return self;
}
- (void)layoutSubviews {
[super layoutSubviews];
[self configureShapeGeneratorWithCornerRadius:self.cornerRadius
centerVisibleArea:self.centerVisibleArea];
}
- (void)setBorderWidth:(CGFloat)borderWidth {
self.layer.shapedBorderWidth = borderWidth;
}
- (CGFloat)borderWidth {
return self.layer.shapedBorderWidth;
}
- (void)setBorderColor:(UIColor *)borderColor {
self.layer.shapedBorderColor = borderColor;
}
- (UIColor *)borderColor {
return self.layer.shapedBorderColor;
}
- (void)setCornerRadius:(CGFloat)cornerRadius {
if (cornerRadius == _cornerRadius) {
return;
}
_cornerRadius = cornerRadius;
[self configureShapeGeneratorWithCornerRadius:cornerRadius
centerVisibleArea:self.centerVisibleArea];
[self setNeedsLayout];
}
- (void)setCenterVisibleArea:(BOOL)centerVisibleArea {
if (centerVisibleArea == _centerVisibleArea) {
return;
}
_centerVisibleArea = centerVisibleArea;
[self configureShapeGeneratorWithCornerRadius:self.cornerRadius
centerVisibleArea:centerVisibleArea];
[self setNeedsLayout];
}
- (void)configureShapeGeneratorWithCornerRadius:(CGFloat)cornerRadius
centerVisibleArea:(BOOL)centerVisibleArea {
MDCCornerTreatment *cornerTreatment =
[[MDCRoundedCornerTreatment alloc] initWithRadius:cornerRadius];
[self.shapeGenerator setCorners:cornerTreatment];
if (centerVisibleArea) {
UIEdgeInsets visibleAreaInsets = UIEdgeInsetsZero;
CGSize visibleAreaSize = CGSizeMake(cornerRadius * 2, cornerRadius * 2);
CGFloat additionalRequiredHeight =
MAX(0, CGRectGetHeight(self.bounds) - visibleAreaSize.height);
CGFloat additionalRequiredWidth = MAX(0, CGRectGetWidth(self.bounds) - visibleAreaSize.width);
visibleAreaInsets.top = ceil(additionalRequiredHeight * 0.5f);
visibleAreaInsets.bottom = additionalRequiredHeight - visibleAreaInsets.top;
visibleAreaInsets.left = ceil(additionalRequiredWidth * 0.5f);
visibleAreaInsets.right = additionalRequiredWidth - visibleAreaInsets.left;
self.shapeGenerator.topLeftCornerOffset =
CGPointMake(visibleAreaInsets.left, visibleAreaInsets.top);
self.shapeGenerator.topRightCornerOffset =
CGPointMake(-visibleAreaInsets.right, visibleAreaInsets.top);
self.shapeGenerator.bottomLeftCornerOffset =
CGPointMake(visibleAreaInsets.left, -visibleAreaInsets.bottom);
self.shapeGenerator.bottomRightCornerOffset =
CGPointMake(-visibleAreaInsets.right, -visibleAreaInsets.bottom);
}
}
- (MDCShadowElevation)elevation {
return self.layer.elevation;
}
- (void)setElevation:(MDCShadowElevation)elevation {
self.layer.elevation = elevation;
}
- (void)setIcon:(nullable UIImage *)icon {
if (icon == _iconView.image || [icon isEqual:_iconView.image])
return;
if (_iconView) {
[_iconView removeFromSuperview];
_iconView = nil;
}
if (icon) {
_iconView = [[UIImageView alloc] initWithImage:icon];
[self addSubview:_iconView];
// Calculate the inner square of the thumbs circle.
CGFloat sideLength = (CGFloat)sin(45.0 / 180.0 * M_PI) * _cornerRadius * 2;
CGFloat topLeft = _cornerRadius - (sideLength / 2);
_iconView.frame = CGRectMake(topLeft, topLeft, sideLength, sideLength);
}
}
- (void)setShadowColor:(UIColor *)shadowColor {
_shadowColor = shadowColor;
self.layer.shadowColor = shadowColor.CGColor;
}
- (void)setBackgroundColor:(UIColor *)backgroundColor {
self.layer.shapedBackgroundColor = backgroundColor;
}
- (UIColor *)backgroundColor {
return self.layer.shapedBackgroundColor;
}
@end