Skip to content

Commit

Permalink
[Tabs] Send tab item title/image to views (#7698)
Browse files Browse the repository at this point in the history
Initial configuration of title and image for itemviews. Does not yet have KVO (coming later). Is using a temporary layout that will be replaced later.

##  Dragon Example Screenshots

|Before|After|
|---|---|
|![Simulator Screen Shot - iPhone 7 - 2019-06-24 at 13 23 15](https://user-images.githubusercontent.com/1753199/60038806-3d030100-9683-11e9-9121-9daa78134e1b.png)|![Simulator Screen Shot - iPhone 7 - 2019-06-24 at 13 20 57](https://user-images.githubusercontent.com/1753199/60038676-fb725600-9682-11e9-83e5-3f0dd7a7669c.png)|


Part of #7697
  • Loading branch information
Robert Moore committed Jun 24, 2019
1 parent f7ac1db commit d202640
Show file tree
Hide file tree
Showing 8 changed files with 147 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,12 @@ - (void)viewDidLoad {

self.view.backgroundColor = self.containerScheme.colorScheme.backgroundColor;

UITabBarItem *item1 = [[UITabBarItem alloc] initWithTitle:@"Home" image:nil tag:0];
UITabBarItem *item2 = [[UITabBarItem alloc] initWithTitle:@"Favorite" image:nil tag:1];
UITabBarItem *item3 = [[UITabBarItem alloc] initWithTitle:@"Cake" image:nil tag:2];

self.tabBar = [[MDCTabBarView alloc] init];
self.tabBar.items = @[ item1, item2, item3 ];
CGSize barIntrinsicContentSize = self.tabBar.intrinsicContentSize;
self.tabBar.bounds = CGRectMake(0, 0, 0, barIntrinsicContentSize.width);
// TODO: Change this to theming (or at least .primaryColor) once we have content.
Expand Down
48 changes: 48 additions & 0 deletions components/Tabs/src/TabBarView/MDCTabBarView.m
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,18 @@
// limitations under the License.

#import "MDCTabBarView.h"
#import "private/MDCTabBarViewItemView.h"

/** Minimum (typical) height of a Material Tab bar. */
static const CGFloat kMinHeight = 48;

@interface MDCTabBarView ()

/** The views representing the items of this tab bar. */
@property(nonatomic, strong) NSArray<UIView *> *itemViews;

@end

@implementation MDCTabBarView

#pragma mark - Initialization
Expand All @@ -25,6 +33,7 @@ - (instancetype)init {
self = [super init];
if (self) {
_items = @[];
_itemViews = @[];
}
return self;
}
Expand All @@ -37,8 +46,25 @@ - (void)setItems:(NSArray<UITabBarItem *> *)items {
if (self.items == items || [self.items isEqual:items]) {
return;
}

for (UIView *itemView in self.itemViews) {
[itemView removeFromSuperview];
}

_items = [items copy];

NSMutableArray<UIView *> *itemViews = [NSMutableArray array];
for (UITabBarItem *item in self.items) {
MDCTabBarViewItemView *itemView = [[MDCTabBarViewItemView alloc] init];
// TODO(#7645): Remove this if autoresizing masks are used.
itemView.translatesAutoresizingMaskIntoConstraints = NO;
itemView.title = item.title;
itemView.image = item.image;
[itemViews addObject:itemView];
[self addSubview:itemView];
}
_itemViews = [itemViews copy];

// Determine new selected item, defaulting to nil.
UITabBarItem *newSelectedItem = nil;
if (self.selectedItem && [self.items containsObject:self.selectedItem]) {
Expand All @@ -47,12 +73,14 @@ - (void)setItems:(NSArray<UITabBarItem *> *)items {
}

self.selectedItem = newSelectedItem;
[self setNeedsLayout];
}

- (void)setSelectedItem:(UITabBarItem *)selectedItem {
if (self.selectedItem == selectedItem) {
return;
}

NSUInteger itemIndex = [self.items indexOfObject:selectedItem];
if (selectedItem && (itemIndex == NSNotFound)) {
NSString *itemTitle = selectedItem.title;
Expand All @@ -65,6 +93,26 @@ - (void)setSelectedItem:(UITabBarItem *)selectedItem {
_selectedItem = selectedItem;
}

#pragma mark - UIView

// TODO(#7645): Temporary layout until
// https://github.com/material-components/material-components-ios/issues/7645 lands
- (void)layoutSubviews {
[super layoutSubviews];

if (self.items.count == 0) {
return;
}
CGSize boundsSize = CGSizeMake(CGRectGetWidth(self.bounds), CGRectGetHeight(self.bounds));
CGSize itemSize = CGSizeMake(boundsSize.width / self.items.count, boundsSize.height);

CGPoint itemOrigin = CGPointMake(CGRectGetMinX(self.bounds), CGRectGetMinY(self.bounds));
for (UIView *itemView in self.itemViews) {
itemView.frame = CGRectMake(itemOrigin.x, itemOrigin.y, itemSize.width, itemSize.height);
itemOrigin = CGPointMake(itemOrigin.x + itemSize.width, itemOrigin.y);
}
}

- (CGSize)intrinsicContentSize {
return CGSizeMake(UIViewNoIntrinsicMetric, kMinHeight);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,29 @@

#import "MDCTabBarView.h"

/** The typical size of an image in a Tab bar. */
static const CGSize kTypicalImageSize = (CGSize){24, 24};

/** The expected height of titles-only or icons-only Tabs. */
static const CGFloat kExpectedHeightTitlesOrIconsOnly = 48;

/** The expected height of Tabs with titles and icons. */
static const CGFloat kExpectedHeightTitlesAndIcons = 72;

@interface MDCTabBarViewSnapshotTests : MDCSnapshotTestCase

/** The view being snapshotted. */
@property(nonatomic, strong) MDCTabBarView *tabBarView;

/** A typically-sized icon image. */
@property(nonatomic, strong) UIImage *typicalIcon1;

/** A typically-sized icon image. */
@property(nonatomic, strong) UIImage *typicalIcon2;

/** A typically-sized icon image. */
@property(nonatomic, strong) UIImage *typicalIcon3;

@end

@implementation MDCTabBarViewSnapshotTests
Expand All @@ -28,6 +49,29 @@ - (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.tabBarView = [[MDCTabBarView alloc] init];
self.tabBarView.backgroundColor = UIColor.whiteColor;
self.tabBarView.bounds = CGRectMake(0, 0, 360, kExpectedHeightTitlesOrIconsOnly);

self.typicalIcon1 = [[UIImage mdc_testImageOfSize:kTypicalImageSize
withStyle:MDCSnapshotTestImageStyleFramedX]
imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
self.typicalIcon2 = [[UIImage mdc_testImageOfSize:kTypicalImageSize
withStyle:MDCSnapshotTestImageStyleDiagonalLines]
imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
self.typicalIcon3 = [[UIImage mdc_testImageOfSize:kTypicalImageSize
withStyle:MDCSnapshotTestImageStyleEllipses]
imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
}

- (void)tearDown {
self.typicalIcon1 = nil;
self.typicalIcon2 = nil;
self.typicalIcon3 = nil;
self.tabBarView = nil;

[super tearDown];
}

#pragma mark - Helpers
Expand All @@ -37,16 +81,60 @@ - (void)generateSnapshotAndVerifyForView:(UIView *)view {
[self snapshotVerifyView:snapshotView];
}

#pragma mark - Tests
#pragma mark - UITabBarItem properties

- (void)testTabBarFixedSize {
- (void)testItemsWithOnlyTitles {
// Given
MDCTabBarView *tabBarView = [[MDCTabBarView alloc] init];
tabBarView.bounds = CGRectMake(0, 0, 120, 56);
tabBarView.backgroundColor = UIColor.blueColor;
UITabBarItem *item1 = [[UITabBarItem alloc] initWithTitle:@"One" image:nil tag:0];
UITabBarItem *item2 = [[UITabBarItem alloc] initWithTitle:@"Two" image:nil tag:2];
UITabBarItem *item3 = [[UITabBarItem alloc] initWithTitle:@"Three" image:nil tag:5];

// When
self.tabBarView.items = @[ item1, item2, item3 ];

// Then
[self generateSnapshotAndVerifyForView:self.tabBarView];
}

- (void)testItemsWithOnlyImages {
// Given
UITabBarItem *item1 = [[UITabBarItem alloc] initWithTitle:nil image:self.typicalIcon1 tag:0];
UITabBarItem *item2 = [[UITabBarItem alloc] initWithTitle:nil image:self.typicalIcon2 tag:2];
UITabBarItem *item3 = [[UITabBarItem alloc] initWithTitle:nil image:self.typicalIcon3 tag:5];

// When
self.tabBarView.items = @[ item1, item2, item3 ];

// Then
[self generateSnapshotAndVerifyForView:self.tabBarView];
}

- (void)testItemsWithTitlesAndImages {
// Given
self.tabBarView.bounds = CGRectMake(0, 0, 360, kExpectedHeightTitlesAndIcons);
UITabBarItem *item1 = [[UITabBarItem alloc] initWithTitle:@"One" image:self.typicalIcon1 tag:0];
UITabBarItem *item2 = [[UITabBarItem alloc] initWithTitle:@"Two" image:self.typicalIcon2 tag:2];
UITabBarItem *item3 = [[UITabBarItem alloc] initWithTitle:@"Three" image:self.typicalIcon3 tag:5];

// When
self.tabBarView.items = @[ item1, item2, item3 ];

// Then
[self generateSnapshotAndVerifyForView:self.tabBarView];
}

- (void)testItemsWithMixedTitlesAndImages {
// Given
self.tabBarView.bounds = CGRectMake(0, 0, 360, kExpectedHeightTitlesAndIcons);
UITabBarItem *item1 = [[UITabBarItem alloc] initWithTitle:@"One" image:nil tag:0];
UITabBarItem *item2 = [[UITabBarItem alloc] initWithTitle:nil image:self.typicalIcon2 tag:2];
UITabBarItem *item3 = [[UITabBarItem alloc] initWithTitle:@"Three" image:self.typicalIcon3 tag:5];

// When
self.tabBarView.items = @[ item1, item2, item3 ];

// Then
[self generateSnapshotAndVerifyForView:tabBarView];
[self generateSnapshotAndVerifyForView:self.tabBarView];
}

@end
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.

0 comments on commit d202640

Please sign in to comment.