Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(87)

Unified Diff: ios/chrome/browser/ui/collection_view/collection_view_controller.mm

Issue 2588713002: Upstream Chrome on iOS source code [4/11]. (Closed)
Patch Set: Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: ios/chrome/browser/ui/collection_view/collection_view_controller.mm
diff --git a/ios/chrome/browser/ui/collection_view/collection_view_controller.mm b/ios/chrome/browser/ui/collection_view/collection_view_controller.mm
new file mode 100644
index 0000000000000000000000000000000000000000..75d4fa7a787a0182b96a05ba95eb49495e12708c
--- /dev/null
+++ b/ios/chrome/browser/ui/collection_view/collection_view_controller.mm
@@ -0,0 +1,267 @@
+// Copyright 2016 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/collection_view/collection_view_controller.h"
+
+#include "base/logging.h"
+#include "base/mac/foundation_util.h"
+#import "base/mac/scoped_nsobject.h"
+#import "ios/chrome/browser/ui/collection_view/cells/collection_view_item.h"
+#import "ios/chrome/browser/ui/collection_view/collection_view_model.h"
+#import "ios/chrome/browser/ui/material_components/utils.h"
+#import "ios/third_party/material_components_ios/src/components/AppBar/src/MaterialAppBar.h"
+#import "ios/third_party/material_components_ios/src/components/CollectionCells/src/MaterialCollectionCells.h"
+
+@implementation CollectionViewController {
+ // The implementation of this controller follows the guidelines from
+ // https://github.com/material-components/material-components-ios/tree/develop/components/AppBar
+ base::scoped_nsobject<MDCAppBar> _appBar;
+ base::scoped_nsobject<CollectionViewModel> _collectionViewModel;
+}
+
+- (instancetype)initWithStyle:(CollectionViewControllerStyle)style {
+ UICollectionViewLayout* layout =
+ [[[MDCCollectionViewFlowLayout alloc] init] autorelease];
+ self = [super initWithCollectionViewLayout:layout];
+ if (self) {
+ if (style == CollectionViewControllerStyleAppBar) {
+ _appBar.reset([[MDCAppBar alloc] init]);
+ [self addChildViewController:_appBar.get().headerViewController];
+ }
+ }
+ return self;
+}
+
+- (void)viewDidLoad {
+ [super viewDidLoad];
+
+ // Configure the app bar, if there is one.
+ if (self.appBar) {
+ // Configure the app bar style.
+ ConfigureAppBarWithCardStyle(self.appBar);
+ // Set the header view's tracking scroll view.
+ self.appBar.headerViewController.headerView.trackingScrollView =
+ self.collectionView;
+ // After all other views have been registered.
+ [self.appBar addSubviewsToParent];
+ }
+}
+
+- (UIViewController*)childViewControllerForStatusBarHidden {
+ return self.appBar.headerViewController;
+}
+
+- (UIViewController*)childViewControllerForStatusBarStyle {
+ return self.appBar.headerViewController;
+}
+
+- (MDCAppBar*)appBar {
+ return _appBar.get();
+}
+
+- (CollectionViewModel*)collectionViewModel {
+ return _collectionViewModel.get();
+}
+
+- (void)loadModel {
+ _collectionViewModel.reset([[CollectionViewModel alloc] init]);
+}
+
+- (void)reconfigureCellsForItems:(NSArray*)items
+ inSectionWithIdentifier:(NSInteger)sectionIdentifier {
+ for (CollectionViewItem* item in items) {
+ NSIndexPath* indexPath =
+ [_collectionViewModel indexPathForItem:item
+ inSectionWithIdentifier:sectionIdentifier];
+ MDCCollectionViewCell* cell =
+ base::mac::ObjCCastStrict<MDCCollectionViewCell>(
+ [self.collectionView cellForItemAtIndexPath:indexPath]);
+
+ // |cell| may be nil if the row is not currently on screen.
+ if (cell) {
+ [item configureCell:cell];
+ }
+ }
+}
+
+#pragma mark MDCCollectionViewEditingDelegate
+
+- (void)collectionView:(UICollectionView*)collectionView
+ willDeleteItemsAtIndexPaths:(NSArray*)indexPaths {
+ // Check that the parent class doesn't implement this method. Otherwise, it
+ // would need to be called here.
+ DCHECK([self isKindOfClass:[MDCCollectionViewController class]]);
+ DCHECK(![MDCCollectionViewController instancesRespondToSelector:_cmd]);
+
+ // Sort and enumerate in reverse order to delete the items from the collection
+ // view model.
+ NSArray* sortedIndexPaths =
+ [indexPaths sortedArrayUsingSelector:@selector(compare:)];
+ for (NSIndexPath* indexPath in [sortedIndexPaths reverseObjectEnumerator]) {
+ NSInteger sectionIdentifier =
+ [_collectionViewModel sectionIdentifierForSection:indexPath.section];
+ NSInteger itemType = [_collectionViewModel itemTypeForIndexPath:indexPath];
+ NSUInteger index =
+ [_collectionViewModel indexInItemTypeForIndexPath:indexPath];
+ [_collectionViewModel removeItemWithType:itemType
+ fromSectionWithIdentifier:sectionIdentifier
+ atIndex:index];
+ }
+}
+
+- (void)collectionView:(UICollectionView*)collectionView
+ willMoveItemAtIndexPath:(NSIndexPath*)indexPath
+ toIndexPath:(NSIndexPath*)newIndexPath {
+ // Check that the parent class doesn't implement this method. Otherwise, it
+ // would need to be called here.
+ DCHECK([self isKindOfClass:[MDCCollectionViewController class]]);
+ DCHECK(![MDCCollectionViewController instancesRespondToSelector:_cmd]);
+
+ // Retain the item to be able to move it.
+ base::scoped_nsobject<CollectionViewItem> item(
+ [[self.collectionViewModel itemAtIndexPath:indexPath] retain]);
+
+ // Item coordinates.
+ NSInteger sectionIdentifier =
+ [self.collectionViewModel sectionIdentifierForSection:indexPath.section];
+ NSInteger itemType =
+ [self.collectionViewModel itemTypeForIndexPath:indexPath];
+ NSUInteger indexInItemType =
+ [self.collectionViewModel indexInItemTypeForIndexPath:indexPath];
+
+ // Move the item.
+ [self.collectionViewModel removeItemWithType:itemType
+ fromSectionWithIdentifier:sectionIdentifier
+ atIndex:indexInItemType];
+ NSInteger section = [self.collectionViewModel
+ sectionIdentifierForSection:newIndexPath.section];
+ [self.collectionViewModel insertItem:item
+ inSectionWithIdentifier:section
+ atIndex:newIndexPath.item];
+}
+
+#pragma mark UICollectionViewDataSource
+
+- (NSInteger)numberOfSectionsInCollectionView:
+ (UICollectionView*)collectionView {
+ return [_collectionViewModel numberOfSections];
+}
+
+- (NSInteger)collectionView:(UICollectionView*)collectionView
+ numberOfItemsInSection:(NSInteger)section {
+ return [_collectionViewModel numberOfItemsInSection:section];
+}
+
+- (UICollectionViewCell*)collectionView:(UICollectionView*)collectionView
+ cellForItemAtIndexPath:(NSIndexPath*)indexPath {
+ CollectionViewItem* item = [_collectionViewModel itemAtIndexPath:indexPath];
+ Class cellClass = [item cellClass];
+ NSString* reuseIdentifier = NSStringFromClass(cellClass);
+ [self.collectionView registerClass:cellClass
+ forCellWithReuseIdentifier:reuseIdentifier];
+ MDCCollectionViewCell* cell = [self.collectionView
+ dequeueReusableCellWithReuseIdentifier:reuseIdentifier
+ forIndexPath:indexPath];
+ [item configureCell:cell];
+ return cell;
+}
+
+- (UICollectionReusableView*)collectionView:(UICollectionView*)collectionView
+ viewForSupplementaryElementOfKind:(NSString*)kind
+ atIndexPath:(NSIndexPath*)indexPath {
+ CollectionViewItem* item = nil;
+ UIAccessibilityTraits traits = UIAccessibilityTraitNone;
+ if ([kind isEqualToString:UICollectionElementKindSectionHeader]) {
+ item = [_collectionViewModel headerForSection:indexPath.section];
+ traits = UIAccessibilityTraitHeader;
+ } else if ([kind isEqualToString:UICollectionElementKindSectionFooter]) {
+ item = [_collectionViewModel footerForSection:indexPath.section];
+ } else {
+ return [super collectionView:collectionView
+ viewForSupplementaryElementOfKind:kind
+ atIndexPath:indexPath];
+ }
+
+ Class cellClass = [item cellClass];
+ NSString* reuseIdentifier = NSStringFromClass(cellClass);
+ [self.collectionView registerClass:cellClass
+ forSupplementaryViewOfKind:kind
+ withReuseIdentifier:reuseIdentifier];
+ MDCCollectionViewCell* cell = [self.collectionView
+ dequeueReusableSupplementaryViewOfKind:kind
+ withReuseIdentifier:reuseIdentifier
+ forIndexPath:indexPath];
+ [item configureCell:cell];
+ cell.accessibilityTraits |= traits;
+ return cell;
+};
+
+#pragma mark - UICollectionViewDelegateFlowLayout
+
+- (CGSize)collectionView:(UICollectionView*)collectionView
+ layout:
+ (UICollectionViewLayout*)collectionViewLayout
+ referenceSizeForHeaderInSection:(NSInteger)section {
+ CollectionViewItem* item = [_collectionViewModel headerForSection:section];
+
+ if (item) {
+ // TODO(crbug.com/635604): Support arbitrary sized headers.
+ return CGSizeMake(0, MDCCellDefaultOneLineHeight);
+ }
+ return CGSizeZero;
+}
+
+- (CGSize)collectionView:(UICollectionView*)collectionView
+ layout:
+ (UICollectionViewLayout*)collectionViewLayout
+ referenceSizeForFooterInSection:(NSInteger)section {
+ CollectionViewItem* item = [_collectionViewModel footerForSection:section];
+
+ if (item) {
+ // TODO(crbug.com/635604): Support arbitrary sized footers.
+ return CGSizeMake(0, MDCCellDefaultOneLineHeight);
+ }
+ return CGSizeZero;
+}
+
+#pragma mark UIScrollViewDelegate
+
+- (void)scrollViewDidScroll:(UIScrollView*)scrollView {
+ MDCFlexibleHeaderView* headerView =
+ self.appBar.headerViewController.headerView;
+ if (scrollView == headerView.trackingScrollView) {
+ [headerView trackingScrollViewDidScroll];
+ }
+}
+
+- (void)scrollViewDidEndDecelerating:(UIScrollView*)scrollView {
+ MDCFlexibleHeaderView* headerView =
+ self.appBar.headerViewController.headerView;
+ if (scrollView == headerView.trackingScrollView) {
+ [headerView trackingScrollViewDidEndDecelerating];
+ }
+}
+
+- (void)scrollViewDidEndDragging:(UIScrollView*)scrollView
+ willDecelerate:(BOOL)decelerate {
+ MDCFlexibleHeaderView* headerView =
+ self.appBar.headerViewController.headerView;
+ if (scrollView == headerView.trackingScrollView) {
+ [headerView trackingScrollViewDidEndDraggingWillDecelerate:decelerate];
+ }
+}
+
+- (void)scrollViewWillEndDragging:(UIScrollView*)scrollView
+ withVelocity:(CGPoint)velocity
+ targetContentOffset:(inout CGPoint*)targetContentOffset {
+ MDCFlexibleHeaderView* headerView =
+ self.appBar.headerViewController.headerView;
+ if (scrollView == headerView.trackingScrollView) {
+ [headerView
+ trackingScrollViewWillEndDraggingWithVelocity:velocity
+ targetContentOffset:targetContentOffset];
+ }
+}
+
+@end

Powered by Google App Engine
This is Rietveld 408576698