Commit 5c22cf8b authored by sczs's avatar sczs Committed by Commit Bot

[ios] Creates TableViewHeaderFooterItem and TableViewTextHeaderFooterItem.

- Creates TableViewHeaderFooterItem and TableViewTextHeaderFooterItem.
- Adds viewForHeaderInSection and viewForFooterInSection in ChromeTableVC.


Table Catalog Screenshot:
https://drive.google.com/open?id=1xKjc3vGVxtkfcz39OdSZY_ENFDO1OnHv

Bug: 805136
Cq-Include-Trybots: master.tryserver.chromium.mac:ios-simulator-cronet;master.tryserver.chromium.mac:ios-simulator-full-configs
Change-Id: I5f3923db7909e6fbf732b0bc8d069d2cfbc6603a
Reviewed-on: https://chromium-review.googlesource.com/942605
Commit-Queue: Sergio Collazos <sczs@chromium.org>
Reviewed-by: default avatarRohit Rao <rohitrao@chromium.org>
Cr-Commit-Position: refs/heads/master@{#540993}
parent 19ef9b19
......@@ -4,6 +4,7 @@
#import "ios/chrome/browser/ui/settings/table_cell_catalog_view_controller.h"
#import "ios/chrome/browser/ui/table_view/cells/table_view_text_header_footer_item.h"
#import "ios/chrome/browser/ui/table_view/cells/table_view_text_item.h"
#import "ios/chrome/browser/ui/table_view/cells/table_view_url_item.h"
#import "ios/chrome/browser/ui/table_view/table_view_model.h"
......@@ -21,6 +22,8 @@ typedef NS_ENUM(NSInteger, SectionIdentifier) {
typedef NS_ENUM(NSInteger, ItemType) {
ItemTypeText = kItemTypeEnumZero,
ItemTypeTextHeader,
ItemTypeTextFooter,
ItemTypeURLNoMetadata,
ItemTypeURLWithTimestamp,
ItemTypeURLWithSize,
......@@ -40,6 +43,8 @@ typedef NS_ENUM(NSInteger, ItemType) {
self.title = @"Table Cell Catalog";
self.tableView.rowHeight = UITableViewAutomaticDimension;
self.tableView.estimatedRowHeight = 56.0;
self.tableView.estimatedSectionHeaderHeight = 56.0;
self.tableView.estimatedSectionFooterHeight = 56.0;
[self loadModel];
}
......@@ -51,11 +56,25 @@ typedef NS_ENUM(NSInteger, ItemType) {
[model addSectionWithIdentifier:SectionIdentifierText];
[model addSectionWithIdentifier:SectionIdentifierURL];
// SectionIdentifierText.
TableViewTextHeaderFooterItem* textHeaderFooterItem =
[[TableViewTextHeaderFooterItem alloc] initWithType:ItemTypeTextHeader];
textHeaderFooterItem.text = @"Simple Text Header";
[model setHeader:textHeaderFooterItem
forSectionWithIdentifier:SectionIdentifierText];
TableViewTextItem* textItem =
[[TableViewTextItem alloc] initWithType:ItemTypeText];
textItem.text = @"Simple Text Cell";
[model addItem:textItem toSectionWithIdentifier:SectionIdentifierText];
textHeaderFooterItem =
[[TableViewTextHeaderFooterItem alloc] initWithType:ItemTypeTextFooter];
textHeaderFooterItem.text = @"Simple Text Footer";
[model setFooter:textHeaderFooterItem
forSectionWithIdentifier:SectionIdentifierText];
// SectionIdentifierURL.
TableViewURLItem* item =
[[TableViewURLItem alloc] initWithType:ItemTypeURLNoMetadata];
item.favicon = [UIImage imageNamed:@"default_favicon"];
......
......@@ -4,8 +4,12 @@
source_set("cells") {
sources = [
"table_view_header_footer_item.h",
"table_view_header_footer_item.mm",
"table_view_item.h",
"table_view_item.mm",
"table_view_text_header_footer_item.h",
"table_view_text_header_footer_item.mm",
"table_view_text_item.h",
"table_view_text_item.mm",
"table_view_url_item.h",
......@@ -23,7 +27,9 @@ source_set("cells") {
source_set("unit_tests") {
testonly = true
sources = [
"table_view_header_footer_item_unittest.mm",
"table_view_item_unittest.mm",
"table_view_text_header_footer_item_unittest.mm",
"table_view_text_item_unittest.mm",
"table_view_url_item_unittest.mm",
]
......
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef IOS_CHROME_BROWSER_UI_TABLE_VIEW_CELLS_TABLE_VIEW_HEADER_FOOTER_ITEM_H_
#define IOS_CHROME_BROWSER_UI_TABLE_VIEW_CELLS_TABLE_VIEW_HEADER_FOOTER_ITEM_H_
#import <UIKit/UIKit.h>
#import "ios/chrome/browser/ui/list_model/list_item.h"
// TableViewHeaderFooterItem holds the model data for a given table view
// header/footer item.
@interface TableViewHeaderFooterItem : ListItem
// Configures the given headerFooter view with the item's information. Override
// this method to specialize. At this level, only accessibility properties are
// ported from the item to the cell. The headerFooter's class must match
// headerFooterClass for the given instance.
- (void)configureHeaderFooterView:(UITableViewHeaderFooterView*)headerFooter
NS_REQUIRES_SUPER;
@end
#endif // IOS_CHROME_BROWSER_UI_TABLE_VIEW_CELLS_TABLE_VIEW_HEADER_FOOTER_ITEM_H_
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#import "ios/chrome/browser/ui/table_view/cells/table_view_header_footer_item.h"
#import "base/logging.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
@implementation TableViewHeaderFooterItem
- (instancetype)initWithType:(NSInteger)type {
if ((self = [super initWithType:type])) {
self.cellClass = [UITableViewHeaderFooterView class];
}
return self;
}
- (void)configureHeaderFooterView:(UITableViewHeaderFooterView*)headerFooter {
DCHECK([headerFooter class] == self.cellClass);
headerFooter.accessibilityTraits = self.accessibilityTraits;
headerFooter.accessibilityIdentifier = self.accessibilityIdentifier;
}
@end
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#import "ios/chrome/browser/ui/table_view/cells/table_view_header_footer_item.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/gtest_mac.h"
#include "testing/platform_test.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
namespace {
using TableViewHeaderFooterItemTest = PlatformTest;
TEST_F(TableViewHeaderFooterItemTest,
ConfigureHeaderFooterPortsAccessibilityProperties) {
TableViewHeaderFooterItem* item =
[[TableViewHeaderFooterItem alloc] initWithType:0];
item.accessibilityIdentifier = @"test_identifier";
item.accessibilityTraits = UIAccessibilityTraitButton;
UITableViewHeaderFooterView* headerFooterView =
[[[item cellClass] alloc] init];
EXPECT_TRUE(
[headerFooterView isMemberOfClass:[UITableViewHeaderFooterView class]]);
EXPECT_EQ(UIAccessibilityTraitNone, [headerFooterView accessibilityTraits]);
EXPECT_FALSE([headerFooterView accessibilityIdentifier]);
[item configureHeaderFooterView:headerFooterView];
EXPECT_EQ(UIAccessibilityTraitButton, [headerFooterView accessibilityTraits]);
EXPECT_NSEQ(@"test_identifier", [headerFooterView accessibilityIdentifier]);
}
} // namespace
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef IOS_CHROME_BROWSER_UI_TABLE_VIEW_CELLS_TABLE_VIEW_TEXT_HEADER_FOOTER_ITEM_H_
#define IOS_CHROME_BROWSER_UI_TABLE_VIEW_CELLS_TABLE_VIEW_TEXT_HEADER_FOOTER_ITEM_H_
#import <UIKit/UIKit.h>
#import "ios/chrome/browser/ui/table_view/cells/table_view_header_footer_item.h"
// TableViewTextHeaderFooterItem contains the model data for a
// UITableViewHeaderFooterView.
@interface TableViewTextHeaderFooterItem : TableViewHeaderFooterItem
@property(nonatomic, readwrite, strong) NSString* text;
@end
// UITableViewHeaderFooterView that displays a text label.
@interface TableViewTextHeaderFooterView : UITableViewHeaderFooterView
@end
#endif // IOS_CHROME_BROWSER_UI_TABLE_VIEW_CELLS_TABLE_VIEW_TEXT_HEADER_FOOTER_ITEM_H_
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#import "ios/chrome/browser/ui/table_view/cells/table_view_text_header_footer_item.h"
#include "base/mac/foundation_util.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
namespace {
// The inner insets of the View content.
const CGFloat kMargin = 16;
}
@implementation TableViewTextHeaderFooterItem
@synthesize text = _text;
- (instancetype)initWithType:(NSInteger)type {
self = [super initWithType:type];
if (self) {
self.cellClass = [TableViewTextHeaderFooterView class];
}
return self;
}
- (void)configureHeaderFooterView:(UITableViewHeaderFooterView*)headerFooter {
[super configureHeaderFooterView:headerFooter];
TableViewTextHeaderFooterView* header =
base::mac::ObjCCastStrict<TableViewTextHeaderFooterView>(headerFooter);
header.textLabel.text = self.text;
}
@end
#pragma mark - TableViewTextHeaderFooter
@implementation TableViewTextHeaderFooterView
@synthesize textLabel = _textLabel;
- (instancetype)initWithReuseIdentifier:(NSString*)reuseIdentifier {
self = [super initWithReuseIdentifier:reuseIdentifier];
if (self) {
// Text Label, set font sizes using dynamic type.
_textLabel = [[UILabel alloc] init];
_textLabel.translatesAutoresizingMaskIntoConstraints = NO;
_textLabel.font = [UIFont preferredFontForTextStyle:UIFontTextStyleBody];
// Container View.
UIView* containerView = [[UIView alloc] init];
containerView.translatesAutoresizingMaskIntoConstraints = NO;
// Add subviews to View Hierarchy.
[containerView addSubview:_textLabel];
[self.contentView addSubview:containerView];
// Set and activate constraints.
[NSLayoutConstraint activateConstraints:@[
// Container Constraints.
[containerView.leadingAnchor
constraintEqualToAnchor:self.contentView.leadingAnchor
constant:kMargin],
[containerView.trailingAnchor
constraintEqualToAnchor:self.contentView.trailingAnchor
constant:-kMargin],
[containerView.topAnchor
constraintGreaterThanOrEqualToAnchor:self.contentView.topAnchor
constant:kMargin],
[containerView.bottomAnchor
constraintLessThanOrEqualToAnchor:self.contentView.bottomAnchor
constant:-kMargin],
[containerView.centerYAnchor
constraintEqualToAnchor:self.contentView.centerYAnchor],
// Title Label Constraints.
[_textLabel.leadingAnchor
constraintEqualToAnchor:containerView.leadingAnchor],
[_textLabel.topAnchor constraintEqualToAnchor:containerView.topAnchor],
[_textLabel.bottomAnchor
constraintEqualToAnchor:containerView.bottomAnchor],
]];
}
return self;
}
@end
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#import "ios/chrome/browser/ui/table_view/cells/table_view_text_header_footer_item.h"
#include "base/mac/foundation_util.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/gtest_mac.h"
#include "testing/platform_test.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
namespace {
using TableViewTextHeaderFooterItemTest = PlatformTest;
}
// Tests that the UILabels are set properly after a call to
// |configureHeaderFooterView:|.
TEST_F(TableViewTextHeaderFooterItemTest, HeaderFooterTextLabels) {
NSString* text = @"HeaderFooter text";
TableViewTextHeaderFooterItem* item =
[[TableViewTextHeaderFooterItem alloc] initWithType:0];
item.text = text;
id headerFooter = [[[item cellClass] alloc] init];
ASSERT_TRUE(
[headerFooter isMemberOfClass:[TableViewTextHeaderFooterView class]]);
TableViewTextHeaderFooterView* textHeaderFooter =
base::mac::ObjCCastStrict<TableViewTextHeaderFooterView>(headerFooter);
EXPECT_FALSE(textHeaderFooter.textLabel.text);
[item configureHeaderFooterView:textHeaderFooter];
EXPECT_NSEQ(text, textHeaderFooter.textLabel.text);
}
......@@ -4,6 +4,7 @@
#import "ios/chrome/browser/ui/table_view/chrome_table_view_controller.h"
#import "ios/chrome/browser/ui/table_view/cells/table_view_header_footer_item.h"
#import "ios/chrome/browser/ui/table_view/cells/table_view_item.h"
#import "ios/chrome/browser/ui/table_view/table_view_model.h"
......@@ -46,4 +47,38 @@
return [self.tableViewModel numberOfSections];
}
#pragma mark - UITableViewDelegate
- (UIView*)tableView:(UITableView*)tableView
viewForHeaderInSection:(NSInteger)section {
TableViewHeaderFooterItem* item =
[self.tableViewModel headerForSection:section];
if (!item)
return [super tableView:self.tableView viewForHeaderInSection:section];
Class headerFooterClass = [item cellClass];
NSString* reuseIdentifier = NSStringFromClass(headerFooterClass);
[self.tableView registerClass:headerFooterClass
forHeaderFooterViewReuseIdentifier:reuseIdentifier];
UITableViewHeaderFooterView* view = [self.tableView
dequeueReusableHeaderFooterViewWithIdentifier:reuseIdentifier];
[item configureHeaderFooterView:view];
return view;
}
- (UIView*)tableView:(UITableView*)tableView
viewForFooterInSection:(NSInteger)section {
TableViewHeaderFooterItem* item =
[self.tableViewModel footerForSection:section];
if (!item)
return [super tableView:self.tableView viewForHeaderInSection:section];
Class headerFooterClass = [item cellClass];
NSString* reuseIdentifier = NSStringFromClass(headerFooterClass);
[self.tableView registerClass:headerFooterClass
forHeaderFooterViewReuseIdentifier:reuseIdentifier];
UITableViewHeaderFooterView* view = [self.tableView
dequeueReusableHeaderFooterViewWithIdentifier:reuseIdentifier];
[item configureHeaderFooterView:view];
return view;
}
@end
......@@ -5,6 +5,7 @@
#import "ios/chrome/browser/ui/table_view/chrome_table_view_controller.h"
#import "ios/chrome/browser/ui/table_view/cells/table_view_item.h"
#import "ios/chrome/browser/ui/table_view/cells/table_view_text_header_footer_item.h"
#import "ios/chrome/browser/ui/table_view/table_view_model.h"
#include "testing/platform_test.h"
......@@ -30,6 +31,24 @@
@end
// Checks that key methods are called.
// TableViewHeaderFooterItem can't easily be mocked via OCMock as one of the
// methods to mock returns a Class type.
@interface FakeTableViewHeaderFooterItem : TableViewHeaderFooterItem
@property(nonatomic, assign) BOOL configureHeaderFooterViewCalled;
@end
@implementation FakeTableViewHeaderFooterItem
@synthesize configureHeaderFooterViewCalled = _configureHeaderFooterViewCalled;
- (void)configureHeaderFooterView:(UITableViewHeaderFooterView*)headerFooter {
self.configureHeaderFooterViewCalled = YES;
[super configureHeaderFooterView:headerFooter];
}
@end
namespace {
typedef NS_ENUM(NSInteger, SectionIdentifier) {
......@@ -59,4 +78,36 @@ TEST_F(ChromeTableViewControllerTest, CellForItemAtIndexPath) {
EXPECT_EQ(YES, [someItem configureCellCalled]);
}
TEST_F(ChromeTableViewControllerTest, HeaderForItemAtSection) {
ChromeTableViewController* controller =
[[ChromeTableViewController alloc] initWithStyle:UITableViewStylePlain];
[controller loadModel];
[[controller tableViewModel] addSectionWithIdentifier:SectionIdentifierFoo];
FakeTableViewHeaderFooterItem* headerItem =
[[FakeTableViewHeaderFooterItem alloc] initWithType:ItemTypeFooBar];
[[controller tableViewModel] setHeader:headerItem
forSectionWithIdentifier:SectionIdentifierFoo];
ASSERT_EQ(NO, [headerItem configureHeaderFooterViewCalled]);
[controller tableView:[controller tableView] viewForHeaderInSection:0];
EXPECT_EQ(YES, [headerItem configureHeaderFooterViewCalled]);
}
TEST_F(ChromeTableViewControllerTest, FooterForItemAtSection) {
ChromeTableViewController* controller =
[[ChromeTableViewController alloc] initWithStyle:UITableViewStylePlain];
[controller loadModel];
[[controller tableViewModel] addSectionWithIdentifier:SectionIdentifierFoo];
FakeTableViewHeaderFooterItem* footerItem =
[[FakeTableViewHeaderFooterItem alloc] initWithType:ItemTypeFooBar];
[[controller tableViewModel] setFooter:footerItem
forSectionWithIdentifier:SectionIdentifierFoo];
ASSERT_EQ(NO, [footerItem configureHeaderFooterViewCalled]);
[controller tableView:[controller tableView] viewForFooterInSection:0];
EXPECT_EQ(YES, [footerItem configureHeaderFooterViewCalled]);
}
} // namespace
......@@ -8,11 +8,12 @@
#import <UIKit/UIKit.h>
#import "ios/chrome/browser/ui/list_model/list_model.h"
#import "ios/chrome/browser/ui/table_view/cells/table_view_header_footer_item.h"
#import "ios/chrome/browser/ui/table_view/cells/table_view_item.h"
// TableViewModel acts as a model class for table view controllers.
@interface TableViewModel<__covariant ObjectType : TableViewItem*>
: ListModel<ObjectType, TableViewItem*>
: ListModel<ObjectType, TableViewHeaderFooterItem*>
@end
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment