Commit 97f68bf9 authored by Mark Cogan's avatar Mark Cogan Committed by Commit Bot

[iOS] Clean up tab grid transition API

In preparation for further fine-tuning, this CL cleans up some of the API and implementation details of the tab grid transition animations.

- The transition layout and transition animations no longer assume (or depend on) the cells being actual UICollectionViewCells. And, since they now can be, the non-active grid cells in the animation are just UIView snapshots.

- The interface into specific subviews and properties needed for animating the active cell is now defined in a protocol.

- GridCell now has two subclasses for the specialized cells used in the transitions; one which just shows the selection ring, and once which can transition from 'cell' to 'tab' appearance.

Bug: 850507
Cq-Include-Trybots: luci.chromium.try:ios-simulator-full-configs;master.tryserver.chromium.mac:ios-simulator-cronet
Change-Id: I7fabc2ab5c522573727b40116789b3080a15a515
Reviewed-on: https://chromium-review.googlesource.com/1135135Reviewed-by: default avataredchin <edchin@chromium.org>
Commit-Queue: Mark Cogan <marq@chromium.org>
Cr-Commit-Position: refs/heads/master@{#575215}
parent af9efb16
......@@ -8,6 +8,7 @@
#import <UIKit/UIKit.h>
#import "ios/chrome/browser/ui/tab_grid/grid/grid_theme.h"
#import "ios/chrome/browser/ui/tab_grid/transitions/grid_to_tab_transition_view.h"
@class GridCell;
......@@ -30,13 +31,21 @@
@property(nonatomic, weak) UIImage* icon;
@property(nonatomic, weak) UIImage* snapshot;
@property(nonatomic, copy) NSString* title;
// Fixed (immutable) UI elements that may be referenced in animations.
@property(nonatomic, readonly, weak) UIView* topBar;
// Returns a cell with the same theme, icon, snapshot, and title as the reciever
// (but no delegate or identifier) for use in animated transitions.
- (GridCell*)proxyForTransitions;
@end
// A GridCell for use in animated transitions that only shows selection state
// (that is, its content view is hidden).
@interface GridTransitionSelectionCell : GridCell
// Returns a transition selection cell with the same theme and frame as |cell|,
// but with no visible content view, no delegate, and no identifier.
+ (instancetype)transitionCellFromCell:(GridCell*)cell;
@end
@interface GridTransitionCell : GridCell<GridToTabTransitionView>
// Returns a cell with the same theme, icon, snapshot, title, and frame as
// |cell| (but no delegate or identifier) for use in animated transitions.
+ (instancetype)transitionCellFromCell:(GridCell*)cell;
@end
#endif // IOS_CHROME_BROWSER_UI_TAB_GRID_GRID_GRID_CELL_H_
......@@ -16,9 +16,8 @@
#endif
@interface GridCell ()
// Redeclare TopBar readwrite internally.
@property(nonatomic, readwrite, weak) UIView* topBar;
// Visual components of the cell.
@property(nonatomic, weak) UIView* topBar;
@property(nonatomic, weak) UIImageView* iconView;
@property(nonatomic, weak) TopAlignedImageView* snapshotView;
@property(nonatomic, weak) UILabel* titleLabel;
......@@ -187,16 +186,6 @@
_title = title;
}
- (GridCell*)proxyForTransitions {
GridCell* proxy = [[[self class] alloc] initWithFrame:self.bounds];
proxy.selected = NO;
proxy.theme = self.theme;
proxy.icon = self.icon;
proxy.snapshot = self.snapshot;
proxy.title = self.title;
return proxy;
}
#pragma mark - Private
// Sets up the top bar with icon, title, and close button.
......@@ -301,3 +290,48 @@
}
@end
@implementation GridTransitionSelectionCell
+ (instancetype)transitionCellFromCell:(GridCell*)cell {
GridTransitionSelectionCell* proxy = [[self alloc] initWithFrame:cell.bounds];
proxy.selected = YES;
proxy.theme = cell.theme;
proxy.contentView.hidden = YES;
return proxy;
}
@end
@implementation GridTransitionCell
+ (instancetype)transitionCellFromCell:(GridCell*)cell {
GridTransitionCell* proxy = [[self alloc] initWithFrame:cell.bounds];
proxy.selected = NO;
proxy.theme = cell.theme;
proxy.icon = cell.icon;
proxy.snapshot = cell.snapshot;
proxy.title = cell.title;
return proxy;
}
#pragma mark - GridToTabTransitionView
- (void)setTopCellView:(UIView*)topCellView {
// The top cell is the top bar and can't be changed.
NOTREACHED();
}
- (UIView*)topCellView {
return self.topBar;
}
- (CGFloat)cornerRadius {
return self.contentView.layer.cornerRadius;
}
- (void)setCornerRadius:(CGFloat)radius {
self.contentView.layer.cornerRadius = radius;
}
@end
......@@ -188,10 +188,9 @@ NSIndexPath* CreateIndexPath(NSInteger index) {
- (GridTransitionLayout*)transitionLayout {
[self.collectionView layoutIfNeeded];
NSMutableArray<GridTransitionLayoutItem*>* items =
[[NSMutableArray alloc] init];
GridTransitionLayoutItem* activeItem;
GridTransitionLayoutItem* selectionItem;
NSMutableArray<GridTransitionItem*>* items = [[NSMutableArray alloc] init];
GridTransitionActiveItem* activeItem;
GridTransitionItem* selectionItem;
for (NSIndexPath* path in self.collectionView.indexPathsForVisibleItems) {
GridCell* cell = base::mac::ObjCCastStrict<GridCell>(
[self.collectionView cellForItemAtIndexPath:path]);
......@@ -201,24 +200,26 @@ NSIndexPath* CreateIndexPath(NSInteger index) {
// change to the other properties such as center, bounds, etc.
attributes.frame =
[self.collectionView convertRect:attributes.frame toView:nil];
GridCell* proxyCell = [cell proxyForTransitions];
GridTransitionLayoutItem* item =
[GridTransitionLayoutItem itemWithCell:proxyCell
auxillaryView:proxyCell.topBar
attributes:attributes];
[items addObject:item];
if ([cell.itemIdentifier isEqualToString:self.selectedItemID]) {
activeItem = item;
selectionItem =
[GridTransitionLayoutItem itemWithCell:[cell proxyForTransitions]
auxillaryView:nil
attributes:attributes];
GridTransitionCell* activeCell =
[GridTransitionCell transitionCellFromCell:cell];
activeItem = [GridTransitionActiveItem itemWithCell:activeCell
center:attributes.center
size:attributes.size];
selectionItem = [GridTransitionItem
itemWithCell:[GridTransitionSelectionCell transitionCellFromCell:cell]
center:attributes.center];
} else {
UIView* cellSnapshot = [cell snapshotViewAfterScreenUpdates:YES];
GridTransitionItem* item =
[GridTransitionItem itemWithCell:cellSnapshot
center:attributes.center];
[items addObject:item];
}
}
return [GridTransitionLayout layoutWithItems:items
activeItem:activeItem
selectionItem:selectionItem];
return [GridTransitionLayout layoutWithInactiveItems:items
activeItem:activeItem
selectionItem:selectionItem];
}
#pragma mark - UICollectionViewDataSource
......
......@@ -6,6 +6,7 @@ import("//ios/public/provider/chrome/browser/build_config.gni")
source_set("transitions") {
sources = [
"grid_to_tab_transition_view.h",
"grid_to_visible_tab_animator.h",
"grid_to_visible_tab_animator.mm",
"grid_transition_animation.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.
#ifndef IOS_CHROME_BROWSER_UI_TAB_GRID_TRANSITIONS_GRID_TO_TAB_TRANSITION_VIEW_H_
#define IOS_CHROME_BROWSER_UI_TAB_GRID_TRANSITIONS_GRID_TO_TAB_TRANSITION_VIEW_H_
#import <UIKit/UIKit.h>
// A protocol to be adopted by a view that will be provided for the transition
// animation. This view will need to be animated between 'cell' and 'tab'
// states, and will need to have a number of properties available for that
// purpose.
@protocol GridToTabTransitionView
// The subview at the top of the view in 'cell' state.
@property(nonatomic, strong) UIView* topCellView;
// The corner radius of the view.
@property(nonatomic) CGFloat cornerRadius;
@end
#endif // IOS_CHROME_BROWSER_UI_TAB_GRID_TRANSITIONS_GRID_TO_TAB_TRANSITION_VIEW_H_
......@@ -5,6 +5,7 @@
#import "ios/chrome/browser/ui/tab_grid/transitions/grid_transition_animation.h"
#import "base/logging.h"
#import "ios/chrome/browser/ui/tab_grid/transitions/grid_to_tab_transition_view.h"
#import "ios/chrome/browser/ui/tab_grid/transitions/grid_transition_layout.h"
#import "ios/chrome/browser/ui/util/property_animator_group.h"
......@@ -27,10 +28,6 @@ const CGFloat kInactiveItemScale = 0.95;
@property(nonatomic, readonly, assign) NSTimeInterval duration;
// The direction this animation is in.
@property(nonatomic, readonly, assign) GridAnimationDirection direction;
// Convenience properties for getting the size and center of the active cell
// in the grid.
@property(nonatomic, readonly) CGSize activeSize;
@property(nonatomic, readonly) CGPoint activeCenter;
// Corner radius that the active cell will have when it is animated into the
// regulat grid.
@property(nonatomic, assign) CGFloat finalActiveCellCornerRadius;
......@@ -51,8 +48,7 @@ const CGFloat kInactiveItemScale = 0.95;
_layout = layout;
_duration = duration;
_direction = direction;
_finalActiveCellCornerRadius =
_layout.activeItem.cell.contentView.layer.cornerRadius;
_finalActiveCellCornerRadius = _layout.activeItem.cell.cornerRadius;
}
return self;
}
......@@ -91,16 +87,6 @@ const CGFloat kInactiveItemScale = 0.95;
[self layoutIfNeeded];
}
#pragma mark - Private Properties
- (CGSize)activeSize {
return self.layout.activeItem.attributes.size;
}
- (CGPoint)activeCenter {
return self.layout.activeItem.attributes.center;
}
#pragma mark - Private methods
- (void)buildContractingAnimations {
......@@ -152,7 +138,7 @@ const CGFloat kInactiveItemScale = 0.95;
[self.animations addAnimator:zoomActiveCell];
// B: Fade in the active cell's auxillary view
UIView* auxillaryView = self.layout.activeItem.auxillaryView;
UIView* auxillaryView = self.layout.activeItem.cell.topCellView;
auto fadeInAuxillaryKeyframeAnimation =
[self keyframeAnimationWithRelativeStart:delay
relativeDuration:briefDuration
......@@ -166,10 +152,10 @@ const CGFloat kInactiveItemScale = 0.95;
[self.animations addAnimator:fadeInAuxillary];
// C: Round the corners of the active cell.
UICollectionViewCell* cell = self.layout.activeItem.cell;
cell.contentView.layer.cornerRadius = 0.0;
UIView<GridToTabTransitionView>* cell = self.layout.activeItem.cell;
cell.cornerRadius = 0.0;
auto roundCornersAnimation = ^{
cell.contentView.layer.cornerRadius = self.finalActiveCellCornerRadius;
cell.cornerRadius = self.finalActiveCellCornerRadius;
};
auto roundCornersKeyframeAnimation =
[self keyframeAnimationWithRelativeStart:0
......@@ -181,17 +167,14 @@ const CGFloat kInactiveItemScale = 0.95;
animations:roundCornersKeyframeAnimation];
[self.animations addAnimator:roundCorners];
if (self.layout.items.count == 1) {
// Single cell case.
// Single cell case.
if (self.layout.inactiveItems.count == 0)
return;
}
// Additional animations for multiple cells.
// D: Scale up inactive cells.
auto scaleUpCellsAnimation = ^{
for (GridTransitionLayoutItem* item in self.layout.items) {
if (item == self.layout.activeItem)
continue;
for (GridTransitionItem* item in self.layout.inactiveItems) {
item.cell.transform = CGAffineTransformIdentity;
}
};
......@@ -208,9 +191,7 @@ const CGFloat kInactiveItemScale = 0.95;
// E: Fade in inactive cells.
auto fadeInCellsAnimation = ^{
for (GridTransitionLayoutItem* item in self.layout.items) {
if (item == self.layout.activeItem)
continue;
for (GridTransitionItem* item in self.layout.inactiveItems) {
item.cell.alpha = 1.0;
}
};
......@@ -267,7 +248,7 @@ const CGFloat kInactiveItemScale = 0.95;
[self.animations addAnimator:zoomActiveCell];
// B: Fade out the active cell's auxillary view.
UIView* auxillaryView = self.layout.activeItem.auxillaryView;
UIView* auxillaryView = self.layout.activeItem.cell.topCellView;
auto fadeOutAuxilliaryAnimation =
[self keyframeAnimationWithRelativeStart:0
relativeDuration:briefDuration
......@@ -281,9 +262,9 @@ const CGFloat kInactiveItemScale = 0.95;
[self.animations addAnimator:fadeOutAuxilliary];
// C: Square the active cell's corners.
UICollectionViewCell* cell = self.layout.activeItem.cell;
UIView<GridToTabTransitionView>* cell = self.layout.activeItem.cell;
auto squareCornersAnimation = ^{
cell.contentView.layer.cornerRadius = 0.0;
cell.cornerRadius = 0.0;
};
auto squareCornersKeyframeAnimation =
[self keyframeAnimationWithRelativeStart:1.0 - briefDuration
......@@ -296,15 +277,13 @@ const CGFloat kInactiveItemScale = 0.95;
[self.animations addAnimator:squareCorners];
// If there's only a single cell, that's all.
if (self.layout.items.count == 1)
if (self.layout.inactiveItems.count == 0)
return;
// Additional animations for multiple cells.
// D: Scale down inactive cells.
auto scaleDownCellsAnimation = ^{
for (GridTransitionLayoutItem* item in self.layout.items) {
if (item == self.layout.activeItem)
continue;
for (GridTransitionItem* item in self.layout.inactiveItems) {
item.cell.transform = CGAffineTransformScale(
item.cell.transform, kInactiveItemScale, kInactiveItemScale);
}
......@@ -317,9 +296,7 @@ const CGFloat kInactiveItemScale = 0.95;
// E: Fade out inactive cells.
auto fadeOutCellsAnimation = ^{
for (GridTransitionLayoutItem* item in self.layout.items) {
if (item == self.layout.activeItem)
continue;
for (GridTransitionItem* item in self.layout.inactiveItems) {
item.cell.alpha = 0.0;
}
};
......@@ -340,44 +317,36 @@ const CGFloat kInactiveItemScale = 0.95;
// Add the selection item first, so it's under ther other views.
[self addSubview:self.layout.selectionItem.cell];
// Only show the selection part.
self.layout.selectionItem.cell.contentView.hidden = YES;
self.layout.selectionItem.cell.selected = YES;
// Add the active item last so it's always the top subview.
for (GridTransitionLayoutItem* item in self.layout.items) {
if (item == self.layout.activeItem)
continue;
for (GridTransitionItem* item in self.layout.inactiveItems) {
[self addSubview:item.cell];
}
// Add the active item last so it's always the top subview.
[self addSubview:self.layout.activeItem.cell];
}
// Positions the active item in the expanded grid position with a zero corner
// radius and a 0% opacity auxilliary view.
- (void)positionExpandedActiveItem {
GridTransitionLayoutItem* activeItem = self.layout.activeItem;
UICollectionViewCell* cell = activeItem.cell;
UIView<GridToTabTransitionView>* cell = self.layout.activeItem.cell;
// Ensure that the cell's subviews are correctly positioned.
[cell layoutIfNeeded];
// Position the cell frame so so that the area below the aux view matches the
// expanded rect.
// Easiest way to do this is to set the frame to the expanded rect and then
// add height to it to include the aux view height.
CGFloat auxHeight = activeItem.auxillaryView.frame.size.height;
CGFloat auxHeight = cell.topCellView.frame.size.height;
CGRect cellFrame = self.layout.expandedRect;
cellFrame.size.height += auxHeight;
cellFrame.origin.y -= auxHeight;
cell.frame = cellFrame;
activeItem.auxillaryView.alpha = 0.0;
cell.topCellView.alpha = 0.0;
}
// Positions all of the inactive items in their grid positions.
// Fades and scales each of those items.
- (void)prepareInactiveItemsForAppearance {
for (GridTransitionLayoutItem* item in self.layout.items) {
if (item == self.layout.activeItem)
continue;
for (GridTransitionItem* item in self.layout.inactiveItems) {
[self positionItemInGrid:item];
item.cell.alpha = 0.0;
item.cell.transform = CGAffineTransformScale(
......@@ -389,26 +358,27 @@ const CGFloat kInactiveItemScale = 0.95;
// Positions the active item in the regular grid position with its final
// corner radius.
- (void)positionAndScaleActiveItemInGrid {
UICollectionViewCell* cell = self.layout.activeItem.cell;
UIView* cell = self.layout.activeItem.cell;
cell.transform = CGAffineTransformIdentity;
cell.frame = self.layout.activeItem.attributes.frame;
CGRect frame = cell.frame;
frame.size = self.layout.activeItem.size;
cell.frame = frame;
[self positionItemInGrid:self.layout.activeItem];
}
// Prepares all of the items for an expansion anumation.
- (void)prepareAllItemsForExpansion {
for (GridTransitionLayoutItem* item in self.layout.items) {
for (GridTransitionItem* item in self.layout.inactiveItems) {
[self positionItemInGrid:item];
}
[self positionItemInGrid:self.layout.activeItem];
[self positionItemInGrid:self.layout.selectionItem];
}
// Positions |item| in it grid position.
- (void)positionItemInGrid:(GridTransitionLayoutItem*)item {
- (void)positionItemInGrid:(GridTransitionItem*)item {
UIView* cell = item.cell;
CGPoint attributeCenter = item.attributes.center;
CGPoint newCenter =
[self.superview convertPoint:attributeCenter fromView:nil];
CGPoint newCenter = [self.superview convertPoint:item.center fromView:nil];
cell.center = newCenter;
}
......
......@@ -7,65 +7,74 @@
#import <UIKit/UIKit.h>
@class GridTransitionLayoutItem;
@protocol GridToTabTransitionView;
@class GridTransitionActiveItem;
@class GridTransitionItem;
// An encapsulation of information for the layout of a grid of cells that will
// be used in an animated transition. The layout object is composed of layout
// items (see below).
@interface GridTransitionLayout : NSObject
// All of the items in the layout.
@property(nonatomic, copy, readonly) NSArray<GridTransitionLayoutItem*>* items;
// The inactive items in the layout. |activeItem| and |selectionItem| are not
// in this array.
@property(nonatomic, copy, readonly)
NSArray<GridTransitionItem*>* inactiveItems;
// The item in the layout (if any) that's the 'active' item (the one that will
// expand and contract).
// Note that |activeItem.cell.selected| doesn't need to be YES; the transition
// animation may set or unset that selection state as part of the animation.
@property(nonatomic, strong, readonly) GridTransitionLayoutItem* activeItem;
@property(nonatomic, strong, readonly) GridTransitionActiveItem* activeItem;
// An item that may be used to *only* show the selection state.
// |selectionItem| is not one of the items in |items|.
@property(nonatomic, strong, readonly) GridTransitionLayoutItem* selectionItem;
// An item that shows the selections state (and nothing else) of the active
// item.
@property(nonatomic, strong, readonly) GridTransitionItem* selectionItem;
// The rect, in UIWindow coordinates, that an "expanded" item should occupy.
@property(nonatomic) CGRect expandedRect;
// Creates a new layout object with |items|, and |activeItem| selected.
// |items| should be non-nil, but it may be empty.
// |activeItem| must either be nil, or one of the members of |items|.
+ (instancetype)layoutWithItems:(NSArray<GridTransitionLayoutItem*>*)items
activeItem:(GridTransitionLayoutItem*)activeItem
selectionItem:(GridTransitionLayoutItem*)selectionItem;
// Creates a new layout object.
// |inactiveItems| should be non-nil, but it may be empty.
// |activeItem| and |selectionItem| may be nil.
+ (instancetype)layoutWithInactiveItems:(NSArray<GridTransitionItem*>*)items
activeItem:(GridTransitionActiveItem*)activeItem
selectionItem:(GridTransitionItem*)selectionItem;
@end
// An encapsulation of information for the layout of a single grid cell.
@interface GridTransitionItem : NSObject
// A view with the desired appearance of the cell for animation. This should
// not be in any view hierarchy when the layout item is created. It should
// otherwise be sized correctly and have the correct appearance.
@property(nonatomic, strong, readonly) UIView* cell;
// The position of |cell| in the grid view, normalized to UIWindow coordinates.
@property(nonatomic, readonly) CGPoint center;
// Creates a new layout item instance with |cell| and |center|. It's the
// responsibility of the caller to normalize |center| to UIWindow coordinates.
// It's an error if |cell| has a superview or is nil.
+ (instancetype)itemWithCell:(UIView*)cell center:(CGPoint)center;
@end
// An encapsulation of information for the layout of a single grid cell, in the
// form of UICollectionView classes.
@interface GridTransitionLayoutItem : NSObject
// A cell object with the desired appearance for the animation. This should
// correspond to an actual cell in the collection view involved in the trans-
// ition, but the value of thie property should not be in any view hierarchy
// when the layout item is created.
@property(nonatomic, strong, readonly) UICollectionViewCell* cell;
// An auxillary view in |cell|'s view hierarchy that may also be animated.
@property(nonatomic, weak, readonly) UIView* auxillaryView;
// The layout attributes for the cell in the collection view, normalized to
// UIWindow coordinates. It's the responsibility of the setter to do this
// normalization.
@property(nonatomic, strong, readonly)
UICollectionViewLayoutAttributes* attributes;
// Creates a new layout item instance will |cell| and |attributes|, neither of
// which can be nil.
// It's an error if |cell| has a superview.
// It's an error if |auxillaryView| is not a subview of |cell|; it may be nil.
// The properties (size, etc) of |attributes| don't need to match the corres-
// ponding properties of |cell| when the item is created.
+ (instancetype)itemWithCell:(UICollectionViewCell*)cell
auxillaryView:(UIView*)auxillaryView
attributes:(UICollectionViewLayoutAttributes*)attributes;
// An extension of GridTransitionItem for an item that will transition between
// 'cell' and 'tab' appearance during the animation.
@interface GridTransitionActiveItem : GridTransitionItem
// A view with the desired appearance of the cell for animation. This should
// not be in any view hierarchy when the layout item is created. It should
// otherwise be sized correctly and have the correct appearance.
@property(nonatomic, strong, readonly) UIView<GridToTabTransitionView>* cell;
// The size of |cell| in the grid.
@property(nonatomic, readonly) CGSize size;
// Creates a new active item instance with |cell|, |center| and |size|.
+ (instancetype)itemWithCell:(UIView<GridToTabTransitionView>*)cell
center:(CGPoint)center
size:(CGSize)size;
@end
......
......@@ -11,56 +11,64 @@
#include "base/logging.h"
@interface GridTransitionLayout ()
@property(nonatomic, readwrite) NSArray<GridTransitionLayoutItem*>* items;
@property(nonatomic, readwrite) GridTransitionLayoutItem* activeItem;
@property(nonatomic, readwrite) GridTransitionLayoutItem* selectionItem;
@property(nonatomic, readwrite) NSArray<GridTransitionItem*>* inactiveItems;
@property(nonatomic, readwrite) GridTransitionActiveItem* activeItem;
@property(nonatomic, readwrite) GridTransitionItem* selectionItem;
@end
@implementation GridTransitionLayout
@synthesize activeItem = _activeItem;
@synthesize selectionItem = _selectionItem;
@synthesize items = _items;
@synthesize inactiveItems = _inactiveItems;
@synthesize expandedRect = _expandedRect;
+ (instancetype)layoutWithItems:(NSArray<GridTransitionLayoutItem*>*)items
activeItem:(GridTransitionLayoutItem*)activeItem
selectionItem:(GridTransitionLayoutItem*)selectionItem {
+ (instancetype)layoutWithInactiveItems:(NSArray<GridTransitionItem*>*)items
activeItem:(GridTransitionActiveItem*)activeItem
selectionItem:(GridTransitionItem*)selectionItem {
DCHECK(items);
GridTransitionLayout* layout = [[GridTransitionLayout alloc] init];
layout.items = items;
layout.inactiveItems = items;
layout.activeItem = activeItem;
layout.selectionItem = selectionItem;
return layout;
}
- (void)setActiveItem:(GridTransitionLayoutItem*)activeItem {
DCHECK(!activeItem || [self.items containsObject:activeItem]);
_activeItem = activeItem;
}
@end
@interface GridTransitionLayoutItem ()
@property(nonatomic, readwrite) UICollectionViewCell* cell;
@property(nonatomic, readwrite) UIView* auxillaryView;
@property(nonatomic, readwrite) UICollectionViewLayoutAttributes* attributes;
@interface GridTransitionItem ()
@property(nonatomic, readwrite) UIView* cell;
@property(nonatomic, readwrite) CGPoint center;
@end
@implementation GridTransitionLayoutItem
@implementation GridTransitionItem
@synthesize cell = _cell;
@synthesize auxillaryView = _auxillaryView;
@synthesize attributes = _attributes;
@synthesize center = _center;
+ (instancetype)itemWithCell:(UICollectionViewCell*)cell
auxillaryView:(UIView*)auxillaryView
attributes:(UICollectionViewLayoutAttributes*)attributes {
+ (instancetype)itemWithCell:(UIView*)cell center:(CGPoint)center {
DCHECK(cell);
DCHECK(!cell.superview);
DCHECK(!auxillaryView || [auxillaryView isDescendantOfView:cell]);
GridTransitionLayoutItem* item = [[GridTransitionLayoutItem alloc] init];
GridTransitionItem* item = [[self alloc] init];
item.cell = cell;
item.auxillaryView = auxillaryView;
item.attributes = attributes;
item.center = center;
return item;
}
@end
@interface GridTransitionActiveItem ()
@property(nonatomic, readwrite) UIView<GridToTabTransitionView>* cell;
@property(nonatomic, readwrite) CGSize size;
@end
@implementation GridTransitionActiveItem
@dynamic cell;
@synthesize size = _size;
+ (instancetype)itemWithCell:(UIView<GridToTabTransitionView>*)cell
center:(CGPoint)center
size:(CGSize)size {
GridTransitionActiveItem* item = [self itemWithCell:cell center:center];
item.size = size;
return item;
}
@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