Skip to content

Commit

Permalink
[Banner] Support Dynamic Type in Banner (#7709)
Browse files Browse the repository at this point in the history
  • Loading branch information
wenyuzhang666 committed Jun 26, 2019
1 parent 60d5f0d commit 7c1b055
Show file tree
Hide file tree
Showing 9 changed files with 377 additions and 67 deletions.

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions catalog/Podfile
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ target "MDCCatalog" do
pod 'MaterialComponentsBeta', :path => '../', :testspecs => [
'ActionSheet+ActionSheetThemer/UnitTests',
'ActionSheet+ColorThemer/UnitTests',
'Banner/UnitTests',
'BottomNavigation/UnitTests',
'ButtonBar+Theming/UnitTests',
'Tabs+TabBarView/UnitTests',
Expand Down
29 changes: 29 additions & 0 deletions components/Banner/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ load(
"mdc_objc_library",
"mdc_snapshot_objc_library",
"mdc_snapshot_test",
"mdc_unit_test_suite",
)

licenses(["notice"]) # Apache 2.0
Expand All @@ -44,6 +45,7 @@ mdc_examples_objc_library(
"//components/Buttons:Theming",
"//components/schemes/Color",
"//components/schemes/Container",
"//components/schemes/Typography",
],
)

Expand All @@ -52,10 +54,37 @@ mdc_snapshot_objc_library(
deps = [
":Banner",
"//components/Buttons",
"//components/schemes/Typography",
],
)

mdc_snapshot_test(
name = "snapshot_tests",
deps = [":snapshot_test_lib"],
)

mdc_objc_library(
name = "unit_test_sources",
testonly = 1,
srcs = native.glob([
"tests/unit/*.m",
"tests/unit/*.h",
]),
sdk_frameworks = [
"UIKit",
"XCTest",
],
visibility = ["//visibility:private"],
deps = [
":Banner",
"//components/Buttons",
"//components/Typography",
],
)

mdc_unit_test_suite(
name = "unit_tests",
deps = [
":unit_test_sources",
],
)
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#import "MaterialButtons.h"
#import "MaterialColorScheme.h"
#import "MaterialTypography.h"
#import "MaterialTypographyScheme.h"

static const CGFloat exampleListTableViewHeight = 160.0f;
static const CGFloat exampleBannerContentPadding = 10.0f;
Expand Down Expand Up @@ -80,6 +81,7 @@ @interface BannerTypicalUseExampleViewController
@property(nonatomic, weak) MDCBannerView *bannerView;

@property(nonatomic, strong) MDCSemanticColorScheme *colorScheme;
@property(nonatomic, strong) MDCTypographyScheme *typographyScheme;

@end

Expand All @@ -89,6 +91,7 @@ - (instancetype)init {
self = [super init];
if (self) {
self.colorScheme = [[MDCSemanticColorScheme alloc] init];
self.typographyScheme = [[MDCTypographyScheme alloc] init];
}
return self;
}
Expand Down Expand Up @@ -220,6 +223,8 @@ - (void)showSingleLineStyleBanner {

MDCBannerView *bannerView = [[MDCBannerView alloc] init];
bannerView.textLabel.text = exampleShortText;
bannerView.textLabel.font = self.typographyScheme.body2;
bannerView.mdc_adjustsFontForContentSizeCategory = YES;
bannerView.backgroundColor = self.colorScheme.surfaceColor;
UIEdgeInsets margins = UIEdgeInsetsZero;
margins.left = exampleBannerContentPadding;
Expand All @@ -232,6 +237,7 @@ - (void)showSingleLineStyleBanner {
[button setTitle:@"Dismiss" forState:UIControlStateNormal];
button.uppercaseTitle = YES;
[button setTitleColor:self.colorScheme.primaryColor forState:UIControlStateNormal];
[button setTitleFont:self.typographyScheme.button forState:UIControlStateNormal];
button.backgroundColor = self.colorScheme.surfaceColor;
bannerView.trailingButton.hidden = YES;
bannerView.imageView.hidden = YES;
Expand Down
12 changes: 12 additions & 0 deletions components/Banner/src/MDCBannerView.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,4 +84,16 @@ __attribute__((objc_subclassing_restricted)) @interface MDCBannerView : UIView
*/
@property(nonatomic, readwrite, strong, nonnull) UIColor *dividerColor;

/*
Indicates whether the banner should automatically update its font when the device’s
UIContentSizeCategory is changed.
If set to YES, the text fonts and buttons font will be based on the scalable fonts set on this
banner.
Default value is NO.
*/
@property(nonatomic, readwrite, setter=mdc_setAdjustsFontForContentSizeCategory:, assign)
BOOL mdc_adjustsFontForContentSizeCategory;

@end
50 changes: 50 additions & 0 deletions components/Banner/src/MDCBannerView.m
Original file line number Diff line number Diff line change
Expand Up @@ -145,12 +145,14 @@ - (void)commonBannerViewInit {
MDCButton *leadingButton = [[MDCButton alloc] init];
leadingButton.translatesAutoresizingMaskIntoConstraints = NO;
leadingButton.backgroundColor = UIColor.whiteColor;
leadingButton.adjustsFontForContentSizeCategoryWhenScaledFontIsUnavailable = NO;
[buttonContainerView addSubview:leadingButton];
_leadingButton = leadingButton;

MDCButton *trailingButton = [[MDCButton alloc] init];
trailingButton.translatesAutoresizingMaskIntoConstraints = NO;
trailingButton.backgroundColor = UIColor.whiteColor;
trailingButton.adjustsFontForContentSizeCategoryWhenScaledFontIsUnavailable = NO;
[buttonContainerView addSubview:trailingButton];
_trailingButton = trailingButton;

Expand Down Expand Up @@ -515,4 +517,52 @@ - (BOOL)isAbleToFitTextLabel:(UILabel *)textLabel withWidthLimit:(CGFloat)widthL
return size.width <= widthLimit;
}

#pragma mark - Font

- (void)mdc_setAdjustsFontForContentSizeCategory:(BOOL)mdc_adjustsFontForContentSizeCategory {
_mdc_adjustsFontForContentSizeCategory = mdc_adjustsFontForContentSizeCategory;

if (mdc_adjustsFontForContentSizeCategory) {
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(contentSizeCategoryDidChange:)
name:UIContentSizeCategoryDidChangeNotification
object:nil];
} else {
[[NSNotificationCenter defaultCenter] removeObserver:self
name:UIContentSizeCategoryDidChangeNotification
object:nil];
}

// Set mdc_adjustsFontForContentSizeCategory on buttons
self.leadingButton.mdc_adjustsFontForContentSizeCategory =
self.mdc_adjustsFontForContentSizeCategory;
self.trailingButton.mdc_adjustsFontForContentSizeCategory =
self.mdc_adjustsFontForContentSizeCategory;

[self updateBannerFont];
}

- (void)contentSizeCategoryDidChange:(__unused NSNotification *)notification {
[self updateBannerFont];
}

- (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection {
[self updateBannerFont];
}

- (void)updateBannerFont {
[self updateTextFont];

[self invalidateIntrinsicContentSize];
[self setNeedsUpdateConstraints];
}

- (void)updateTextFont {
UIFont *textFont = self.textLabel.font;
if (self.mdc_adjustsFontForContentSizeCategory && textFont.mdc_scalingCurve) {
textFont = [textFont mdc_scaledFontForTraitEnvironment:self];
}
self.textLabel.font = textFont;
}

@end
104 changes: 103 additions & 1 deletion components/Banner/tests/snapshot/MDCBannerSnapshotTests.m
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,56 @@

#import "MDCBannerView.h"
#import "MaterialButtons.h"
#import "MaterialTypographyScheme.h"

static NSString *const kBannerShortText = @"tristique senectus et";
static NSString *const kBannerLongText =
@"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt.";
static const CGFloat kBannerContentPadding = 10.0f;

@interface MDCBannerViewSnapshotDynamicTypeContentSizeCategoryOverrideWindow : UIWindow

/** Used to override the value of @c preferredContentSizeCategory. */
@property(nonatomic, copy) UIContentSizeCategory contentSizeCategoryOverride;

@end

@implementation MDCBannerViewSnapshotDynamicTypeContentSizeCategoryOverrideWindow

- (instancetype)init {
self = [super init];
if (self) {
self.contentSizeCategoryOverride = UIContentSizeCategoryLarge;
}
return self;
}

- (instancetype)initWithContentSizeCategoryOverride:
(UIContentSizeCategory)contentSizeCategoryOverride {
self = [super init];
if (self) {
self.contentSizeCategoryOverride = contentSizeCategoryOverride;
}
return self;
}

- (UITraitCollection *)traitCollection {
if (@available(iOS 10.0, *)) {
UITraitCollection *traitCollection = [UITraitCollection
traitCollectionWithPreferredContentSizeCategory:self.contentSizeCategoryOverride];
return traitCollection;
}
return [super traitCollection];
}

@end

/** Snapshot tests for MDCBannerView. */
@interface MDCBannerViewSnapshotTests : MDCSnapshotTestCase

/** The view being tested. */
@property(nonatomic, strong) MDCBannerView *bannerView;
@property(nonatomic, strong) MDCTypographyScheme *typographyScheme;

@end

Expand All @@ -37,7 +76,7 @@ - (void)setUp {

// Uncomment below to recreate all the goldens (or add the following line to the specific
// test you wish to recreate the golden for).
// self.recordMode = YES;
// self.recordMode = YES;

self.bannerView = [[MDCBannerView alloc] initWithFrame:CGRectZero];
if (@available(iOS 11.0, *)) {
Expand All @@ -59,6 +98,25 @@ - (void)tearDown {
[super tearDown];
}

- (UIWindow *)generateWindowWithView:(UIView *)view
contentSizeCategory:(UIContentSizeCategory)sizeCategory
insets:(UIEdgeInsets)insets {
MDCBannerViewSnapshotDynamicTypeContentSizeCategoryOverrideWindow *backgroundWindow =
[[MDCBannerViewSnapshotDynamicTypeContentSizeCategoryOverrideWindow alloc]
initWithFrame:CGRectMake(0, 0, CGRectGetWidth(view.bounds) + insets.left + insets.right,
CGRectGetHeight(view.bounds) + insets.top + insets.bottom)];
backgroundWindow.contentSizeCategoryOverride = sizeCategory;
backgroundWindow.backgroundColor = [UIColor colorWithWhite:(CGFloat)0.8 alpha:1];
[backgroundWindow addSubview:view];
backgroundWindow.hidden = NO;

CGRect frame = view.frame;
frame.origin = CGPointMake(insets.left, insets.top);
view.frame = frame;

return backgroundWindow;
}

- (void)generateSnapshotAndVerifyForView:(UIView *)view {
CGSize aSize = [view sizeThatFits:CGSizeMake(350, INFINITY)];
view.frame = CGRectMake(0, 0, aSize.width, aSize.height);
Expand All @@ -68,6 +126,25 @@ - (void)generateSnapshotAndVerifyForView:(UIView *)view {
[self snapshotVerifyView:snapshotView];
}

// TODO(https://github.com/material-components/material-components-ios/issues/7487):
// The size of the cell view sent for snapshot is not correct because Autolayout needs
// to be used as an environment.
- (void)generateSnapshotWithContentSizeCategoryAndNotificationPost:
(UIContentSizeCategory)sizeCategory
andVerifyForView:(UIView *)view {
CGSize aSize = [view sizeThatFits:CGSizeMake(350, INFINITY)];
view.frame = CGRectMake(0, 0, aSize.width, aSize.height);
[view layoutIfNeeded];

UIWindow *snapshotWindow = [self generateWindowWithView:view
contentSizeCategory:sizeCategory
insets:UIEdgeInsetsMake(10, 10, 10, 10)];
[NSNotificationCenter.defaultCenter
postNotificationName:UIContentSizeCategoryDidChangeNotification
object:nil];
[self snapshotVerifyView:snapshotWindow];
}

- (void)changeViewToRTL:(UIView *)view {
if (@available(iOS 9.0, *)) {
view.semanticContentAttribute = UISemanticContentAttributeForceRightToLeft;
Expand Down Expand Up @@ -201,4 +278,29 @@ - (void)testSingleRowStyleLongTextWithSingleActionRTL {
[self generateSnapshotAndVerifyForView:self.bannerView];
}

- (void)testDynamicTypeForContentSizeCategoryExtraExtraLarge {
if (@available(iOS 10.0, *)) {
// Given
self.bannerView = [[MDCBannerView alloc] init];
self.typographyScheme =
[[MDCTypographyScheme alloc] initWithDefaults:MDCTypographySchemeDefaultsMaterial201902];

// When
self.bannerView.textLabel.text = kBannerShortText;
self.bannerView.textLabel.font = self.typographyScheme.body2;
MDCButton *button = self.bannerView.leadingButton;
[button setTitle:@"Action" forState:UIControlStateNormal];
[button setTitleFont:self.typographyScheme.button forState:UIControlStateNormal];
button.uppercaseTitle = YES;
[button setTitleColor:UIColor.blackColor forState:UIControlStateNormal];
self.bannerView.trailingButton.hidden = YES;
self.bannerView.mdc_adjustsFontForContentSizeCategory = YES;

// Then
[self generateSnapshotWithContentSizeCategoryAndNotificationPost:
UIContentSizeCategoryExtraExtraLarge
andVerifyForView:self.bannerView];
}
}

@end

0 comments on commit 7c1b055

Please sign in to comment.