blob: 847bd25a85411b4b5e7961f55ed6294e6b890bbf [file] [log] [blame] [edit]
// Copyright 2018-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 "MDCShapeSchemeExampleViewController.h"
#import "supplemental/MDCBottomSheetControllerShapeThemerDefaultMapping.h"
#import "supplemental/MDCChipViewShapeThemerDefaultMapping.h"
#import "supplemental/MDCFloatingButtonShapeThemerDefaultMapping.h"
#import "supplemental/MDCShapeExamplesDummyCollectionViewController.h"
#import "MaterialAppBar+ColorThemer.h"
#import "MaterialAppBar+TypographyThemer.h"
#import "MaterialAppBar.h"
#import "MaterialBottomSheet+ShapeThemer.h"
#import "MaterialBottomSheet.h"
#import "MaterialButtons+ButtonThemer.h"
#import "MaterialButtons+ShapeThemer.h"
#import "MaterialButtons+Theming.h"
#import "MaterialButtons.h"
#import "MaterialCards+ShapeThemer.h"
#import "MaterialCards+Theming.h"
#import "MaterialCards.h"
#import "MaterialChips+ShapeThemer.h"
#import "MaterialChips+Theming.h"
#import "MaterialChips.h"
#import "MaterialColorScheme.h"
#import "MaterialContainerScheme.h"
#import "MaterialShapeLibrary.h"
#import "MaterialShapeScheme.h"
#import "MaterialTypographyScheme.h"
@interface MDCShapeSchemeExampleViewController ()
@property(strong, nonatomic) MDCSemanticColorScheme *colorScheme;
@property(strong, nonatomic) MDCShapeScheme *shapeScheme;
@property(strong, nonatomic) MDCTypographyScheme *typographyScheme;
@property(strong, nonatomic) MDCContainerScheme *containerScheme;
@property(weak, nonatomic) IBOutlet MDCShapedView *smallComponentShape;
@property(weak, nonatomic) IBOutlet MDCShapedView *mediumComponentShape;
@property(weak, nonatomic) IBOutlet MDCShapedView *largeComponentShape;
@property(weak, nonatomic) IBOutlet UISegmentedControl *smallComponentType;
@property(weak, nonatomic) IBOutlet UISegmentedControl *mediumComponentType;
@property(weak, nonatomic) IBOutlet UISegmentedControl *largeComponentType;
@property(weak, nonatomic) IBOutlet UISlider *smallComponentValue;
@property(weak, nonatomic) IBOutlet UISlider *mediumComponentValue;
@property(weak, nonatomic) IBOutlet UISlider *largeComponentValue;
@property(weak, nonatomic) IBOutlet UISegmentedControl *includeBaselineOverridesToggle;
@property(weak, nonatomic) IBOutlet UIView *componentContentView;
@property(strong, nonatomic) MDCButton *containedButton;
@property(strong, nonatomic) MDCButton *outlinedButton;
@property(strong, nonatomic) MDCFloatingButton *floatingButton;
@property(strong, nonatomic) MDCChipView *chipView;
@property(strong, nonatomic) MDCCard *card;
@property(strong, nonatomic) MDCButton *presentBottomSheetButton;
@property(strong, nonatomic) MDCBottomSheetController *bottomSheetController;
@end
@implementation MDCShapeSchemeExampleViewController
- (instancetype)init {
self = [super init];
if (self) {
[self commonShapeSchemeExampleInit];
}
return self;
}
- (instancetype)initWithCoder:(NSCoder *)coder {
self = [super initWithCoder:coder];
if (self) {
[self commonShapeSchemeExampleInit];
}
return self;
}
- (void)commonShapeSchemeExampleInit {
self.colorScheme =
[[MDCSemanticColorScheme alloc] initWithDefaults:MDCColorSchemeDefaultsMaterial201804];
self.shapeScheme = [[MDCShapeScheme alloc] initWithDefaults:MDCShapeSchemeDefaultsMaterial201809];
self.typographyScheme =
[[MDCTypographyScheme alloc] initWithDefaults:MDCTypographySchemeDefaultsMaterial201804];
self.containerScheme = [[MDCContainerScheme alloc] init];
self.containerScheme.colorScheme = self.colorScheme;
self.containerScheme.shapeScheme = self.shapeScheme;
self.containerScheme.typographyScheme = self.typographyScheme;
}
- (void)viewDidLoad {
[super viewDidLoad];
_smallComponentShape.shapeGenerator = [[MDCRectangleShapeGenerator alloc] init];
_mediumComponentShape.shapeGenerator = [[MDCRectangleShapeGenerator alloc] init];
_largeComponentShape.shapeGenerator = [[MDCRectangleShapeGenerator alloc] init];
[self applySchemeColors];
[self initializeComponentry];
}
- (void)initializeComponentry {
self.containedButton = [[MDCButton alloc] init];
[self.containedButton setTitle:@"Button" forState:UIControlStateNormal];
[self.containedButton applyContainedThemeWithScheme:self.containerScheme];
self.containedButton.translatesAutoresizingMaskIntoConstraints = NO;
[self.componentContentView addSubview:self.containedButton];
self.floatingButton = [[MDCFloatingButton alloc] init];
UIImage *plusImage =
[[UIImage imageNamed:@"Plus"] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
[self.floatingButton setImage:plusImage forState:UIControlStateNormal];
[self.floatingButton applySecondaryThemeWithScheme:[self containerScheme]];
[self.floatingButton sizeToFit];
self.floatingButton.translatesAutoresizingMaskIntoConstraints = NO;
[self.componentContentView addSubview:self.floatingButton];
self.chipView = [[MDCChipView alloc] init];
self.chipView.titleLabel.text = @"Material";
self.chipView.imageView.image = [self faceImage];
self.chipView.accessoryView = [self deleteButton];
self.chipView.minimumSize = CGSizeMake(140, 33);
self.chipView.translatesAutoresizingMaskIntoConstraints = NO;
[self.chipView applyThemeWithScheme:self.containerScheme];
[self.componentContentView addSubview:self.chipView];
self.card = [[MDCCard alloc] init];
self.card.translatesAutoresizingMaskIntoConstraints = NO;
[self.card applyThemeWithScheme:self.containerScheme];
self.card.backgroundColor = _colorScheme.primaryColor;
[self.componentContentView addSubview:self.card];
NSArray<NSLayoutConstraint *> *cardConstraints =
[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-[card]-|"
options:0
metrics:nil
views:@{@"card" : self.card}];
[self.view addConstraints:cardConstraints];
self.presentBottomSheetButton = [[MDCButton alloc] init];
[self.presentBottomSheetButton setTitle:@"Present Bottom Sheet" forState:UIControlStateNormal];
[self.presentBottomSheetButton applyOutlinedThemeWithScheme:self.containerScheme];
self.presentBottomSheetButton.translatesAutoresizingMaskIntoConstraints = NO;
[self.componentContentView addSubview:self.presentBottomSheetButton];
[self.presentBottomSheetButton addTarget:self
action:@selector(presentBottomSheet)
forControlEvents:UIControlEventTouchUpInside];
NSArray<NSLayoutConstraint *> *bottomSheetConstraints = [NSLayoutConstraint
constraintsWithVisualFormat:@"H:|-[presentBottomSheetButton]-|"
options:0
metrics:nil
views:@{@"presentBottomSheetButton" : self.presentBottomSheetButton}];
[self.view addConstraints:bottomSheetConstraints];
NSArray<NSLayoutConstraint *> *componentConstraints = [NSLayoutConstraint
constraintsWithVisualFormat:@"V:|-(30)-[containedButton]-(20)-[floatingButton]-(20)-["
@"chipView]-(20)-[card(80)]-(20)-[presentBottomSheetButton]"
options:NSLayoutFormatAlignAllCenterX
metrics:nil
views:@{
@"containedButton" : self.containedButton,
@"floatingButton" : self.floatingButton,
@"chipView" : self.chipView,
@"card" : self.card,
@"presentBottomSheetButton" : self.presentBottomSheetButton
}];
[self.view addConstraints:componentConstraints];
}
- (void)presentBottomSheet {
MDCShapeExamplesDummyCollectionViewController *viewController =
[[MDCShapeExamplesDummyCollectionViewController alloc] initWithNumItems:102];
viewController.title = @"Shaped bottom sheet example";
MDCAppBarContainerViewController *container =
[[MDCAppBarContainerViewController alloc] initWithContentViewController:viewController];
container.preferredContentSize = CGSizeMake(500, 200);
container.appBarViewController.headerView.trackingScrollView = viewController.collectionView;
container.topLayoutGuideAdjustmentEnabled = YES;
[MDCAppBarColorThemer applyColorScheme:self.colorScheme
toAppBarViewController:container.appBarViewController];
[MDCAppBarTypographyThemer applyTypographyScheme:self.typographyScheme
toAppBarViewController:container.appBarViewController];
self.bottomSheetController =
[[MDCBottomSheetController alloc] initWithContentViewController:container];
self.bottomSheetController.trackingScrollView = viewController.collectionView;
[self updateComponentShapesWithBaselineOverrides:self.includeBaselineOverridesToggle
.selectedSegmentIndex == 0];
[self presentViewController:self.bottomSheetController animated:YES completion:nil];
}
- (UIImage *)faceImage {
NSBundle *bundle = [NSBundle bundleForClass:[MDCShapeSchemeExampleViewController class]];
UIImage *image = [UIImage imageNamed:@"ic_mask"
inBundle:bundle
compatibleWithTraitCollection:nil];
return image;
}
- (UIButton *)deleteButton {
NSBundle *bundle = [NSBundle bundleForClass:[MDCShapeSchemeExampleViewController class]];
UIImage *image = [UIImage imageNamed:@"ic_cancel"
inBundle:bundle
compatibleWithTraitCollection:nil];
image = [image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
UIButton *button = [[UIButton alloc] initWithFrame:CGRectZero];
button.tintColor = [UIColor colorWithWhite:0 alpha:(CGFloat)0.7];
[button setImage:image forState:UIControlStateNormal];
return button;
}
- (void)applySchemeColors {
_smallComponentShape.backgroundColor = _colorScheme.primaryColor;
_mediumComponentShape.backgroundColor = _colorScheme.primaryColor;
_largeComponentShape.backgroundColor = _colorScheme.primaryColor;
[_smallComponentType setTintColor:_colorScheme.primaryColor];
[_mediumComponentType setTintColor:_colorScheme.primaryColor];
[_largeComponentType setTintColor:_colorScheme.primaryColor];
[_includeBaselineOverridesToggle setTintColor:_colorScheme.primaryColor];
}
- (void)updateShapeSchemeValues {
MDCRectangleShapeGenerator *smallRect =
(MDCRectangleShapeGenerator *)_smallComponentShape.shapeGenerator;
smallRect.topLeftCorner = _shapeScheme.smallComponentShape.topLeftCorner;
smallRect.topRightCorner = _shapeScheme.smallComponentShape.topRightCorner;
smallRect.bottomLeftCorner = _shapeScheme.smallComponentShape.bottomLeftCorner;
smallRect.bottomRightCorner = _shapeScheme.smallComponentShape.bottomRightCorner;
_smallComponentShape.shapeGenerator = smallRect;
MDCRectangleShapeGenerator *mediumRect =
(MDCRectangleShapeGenerator *)_mediumComponentShape.shapeGenerator;
mediumRect.topLeftCorner = _shapeScheme.mediumComponentShape.topLeftCorner;
mediumRect.topRightCorner = _shapeScheme.mediumComponentShape.topRightCorner;
mediumRect.bottomLeftCorner = _shapeScheme.mediumComponentShape.bottomLeftCorner;
mediumRect.bottomRightCorner = _shapeScheme.mediumComponentShape.bottomRightCorner;
_mediumComponentShape.shapeGenerator = mediumRect;
MDCRectangleShapeGenerator *largeRect =
(MDCRectangleShapeGenerator *)_largeComponentShape.shapeGenerator;
largeRect.topLeftCorner = _shapeScheme.largeComponentShape.topLeftCorner;
largeRect.topRightCorner = _shapeScheme.largeComponentShape.topRightCorner;
largeRect.bottomLeftCorner = _shapeScheme.largeComponentShape.bottomLeftCorner;
largeRect.bottomRightCorner = _shapeScheme.largeComponentShape.bottomRightCorner;
_largeComponentShape.shapeGenerator = largeRect;
[self updateComponentShapes];
}
- (void)updateComponentShapes {
[MDCButtonShapeThemer applyShapeScheme:_shapeScheme toButton:self.containedButton];
[MDCButtonShapeThemer applyShapeScheme:_shapeScheme toButton:self.outlinedButton];
[MDCCardsShapeThemer applyShapeScheme:_shapeScheme toCard:self.card];
[MDCButtonShapeThemer applyShapeScheme:_shapeScheme toButton:self.presentBottomSheetButton];
[self updateComponentShapesWithBaselineOverrides:self.includeBaselineOverridesToggle
.selectedSegmentIndex == 0];
}
- (MDCShapeCategory *)changedCategoryFromType:(UISegmentedControl *)sender
andValue:(UISlider *)slider {
MDCShapeCategory *changedCategory;
if ([[sender titleForSegmentAtIndex:sender.selectedSegmentIndex] isEqualToString:@"Cut"]) {
// Cut Corner
changedCategory = [[MDCShapeCategory alloc] initCornersWithFamily:MDCShapeCornerFamilyCut
andSize:slider.value];
} else {
// Rounded Corner
changedCategory = [[MDCShapeCategory alloc] initCornersWithFamily:MDCShapeCornerFamilyRounded
andSize:slider.value];
}
return changedCategory;
}
- (IBAction)smallComponentTypeChanged:(UISegmentedControl *)sender {
_shapeScheme.smallComponentShape = [self changedCategoryFromType:sender
andValue:_smallComponentValue];
[self updateShapeSchemeValues];
}
- (IBAction)smallComponentValueChanged:(UISlider *)sender {
_shapeScheme.smallComponentShape = [self changedCategoryFromType:_smallComponentType
andValue:sender];
[self updateShapeSchemeValues];
}
- (IBAction)mediumComponentTypeChanged:(UISegmentedControl *)sender {
_shapeScheme.mediumComponentShape = [self changedCategoryFromType:sender
andValue:_mediumComponentValue];
[self updateShapeSchemeValues];
}
- (IBAction)mediumComponentValueChanged:(UISlider *)sender {
_shapeScheme.mediumComponentShape = [self changedCategoryFromType:_mediumComponentType
andValue:sender];
[self updateShapeSchemeValues];
}
- (IBAction)largeComponentTypeChanged:(UISegmentedControl *)sender {
_shapeScheme.largeComponentShape = [self changedCategoryFromType:sender
andValue:_largeComponentValue];
[self updateShapeSchemeValues];
}
- (IBAction)largeComponentValueChanged:(UISlider *)sender {
_shapeScheme.largeComponentShape = [self changedCategoryFromType:_largeComponentType
andValue:sender];
[self updateShapeSchemeValues];
}
- (IBAction)baselineOverrideValueChanged:(UISegmentedControl *)sender {
[self updateComponentShapesWithBaselineOverrides:sender.selectedSegmentIndex == 0];
}
- (void)updateComponentShapesWithBaselineOverrides:(BOOL)baselineOverrides {
if (!baselineOverrides) {
// We don't want baseline overrides.
[MDCBottomSheetControllerShapeThemerDefaultMapping applyShapeScheme:_shapeScheme
toBottomSheetController:self.bottomSheetController];
[MDCChipViewShapeThemerDefaultMapping applyShapeScheme:_shapeScheme toChipView:self.chipView];
[MDCFloatingButtonShapeThemerDefaultMapping applyShapeScheme:_shapeScheme
toButton:self.floatingButton];
} else {
// We do want baseline overrides.
[MDCBottomSheetControllerShapeThemer applyShapeScheme:_shapeScheme
toBottomSheetController:self.bottomSheetController];
[MDCChipViewShapeThemer applyShapeScheme:_shapeScheme toChipView:self.chipView];
[MDCFloatingButtonShapeThemer applyShapeScheme:_shapeScheme toButton:self.floatingButton];
}
}
@end
#pragma mark - Catalog by convention
@implementation MDCShapeSchemeExampleViewController (CatlogByConvention)
+ (NSDictionary *)catalogMetadata {
return @{
@"breadcrumbs" : @[ @"Shape", @"ShapeScheme" ],
@"description" :
@"The Shape scheme and theming allows components to be shaped on a theme level",
@"primaryDemo" : @YES,
@"presentable" : @NO,
@"storyboardName" : @"MDCShapeSchemeExampleViewController",
};
}
@end