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

Unified Diff: ios/chrome/browser/ui/tab_switcher/tab_switcher_tab_strip_placeholder_view.mm

Issue 2588733002: Upstream Chrome on iOS source code [9/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/tab_switcher/tab_switcher_tab_strip_placeholder_view.mm
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_switcher_tab_strip_placeholder_view.mm b/ios/chrome/browser/ui/tab_switcher/tab_switcher_tab_strip_placeholder_view.mm
new file mode 100644
index 0000000000000000000000000000000000000000..fda92e3d8ea2271b2b2eb0071f57700c6a8da20b
--- /dev/null
+++ b/ios/chrome/browser/ui/tab_switcher/tab_switcher_tab_strip_placeholder_view.mm
@@ -0,0 +1,166 @@
+// 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.
+
+#include "ios/chrome/browser/ui/tab_switcher/tab_switcher_tab_strip_placeholder_view.h"
+
+#include <algorithm>
+
+#import <QuartzCore/QuartzCore.h>
+
+#import "base/ios/weak_nsobject.h"
+#include "base/mac/foundation_util.h"
+#include "base/mac/scoped_nsobject.h"
+#include "ios/chrome/browser/ui/rtl_geometry.h"
+
+// Returns the animation drag coefficient set by the iPhone simulator.
+// This is useful when debugging with the simulator because when
+// "slow animation" mode is toggled, it only impacts UIKit animations not
+// CoreAnimation animations. By reading the value of that
+// UIAnimatonDragCoefficient API we can also slow down Core Animation animations
+// with the right value.
+// On device we always return 1.0 because it's using private API.
+#if TARGET_IPHONE_SIMULATOR
+UIKIT_EXTERN float UIAnimationDragCoefficient();
+float animationDragCoefficient() {
+ return UIAnimationDragCoefficient();
+}
+#else
+float animationDragCoefficient() {
+ return 1.0f;
+}
+#endif
+
+@interface TabSwitcherTabStripPlaceholderView () {
+ // YES when the fold animation is currently playing.
+ BOOL _animatingFold;
+}
+
+// Adds a transform animation to |layer| with |duration|, |beginTime|,
+// from value |from| to value |to|. The animation will be reversed if |reverse|
+// is set to true.
+- (void)addTransformAnimationToLayer:(CALayer*)layer
+ duration:(CFTimeInterval)duration
+ beginTime:(CFTimeInterval)beginTime
+ from:(CATransform3D)from
+ to:(CATransform3D)to
+ reverse:(BOOL)reverse;
+
+// Triggers a fold animation if |fold| is true and an unfold aniamtion if |fold|
+// is false. The |completion| block is called at the end of the animation.
+- (void)animateFold:(BOOL)fold withCompletion:(ProceduralBlock)completion;
+
+@end
+
+namespace {
+// Tab strip fold animation total duration in seconds.
+const CGFloat kFoldAnimationDuration = 0.25;
+// Tab strip fold animation duration in seconds for a single tab view.
+const CGFloat kTabFoldAnimationDuration = 0.15;
+}
+
+@implementation TabSwitcherTabStripPlaceholderView
+
+- (instancetype)initWithFrame:(CGRect)frame {
+ self = [super initWithFrame:frame];
+ if (self) {
+ self.backgroundColor = [UIColor clearColor];
+ if (UseRTLLayout())
+ [self setTransform:CGAffineTransformMakeScale(-1, 1)];
+ }
+ return self;
+}
+
+- (void)foldWithCompletion:(ProceduralBlock)completion {
+ [self animateFold:YES withCompletion:completion];
+}
+
+- (void)unfoldWithCompletion:(ProceduralBlock)completion {
+ [self animateFold:NO withCompletion:completion];
+}
+
+#pragma mark - Private
+
+- (void)addTransformAnimationToLayer:(CALayer*)layer
+ duration:(CFTimeInterval)duration
+ beginTime:(CFTimeInterval)beginTime
+ from:(CATransform3D)from
+ to:(CATransform3D)to
+ reverse:(BOOL)reverse {
+ CABasicAnimation* transformAnimation =
+ [CABasicAnimation animationWithKeyPath:@"transform"];
+ transformAnimation.duration = animationDragCoefficient() * duration;
+ transformAnimation.beginTime = beginTime;
+ transformAnimation.fromValue =
+ [NSValue valueWithCATransform3D:(reverse ? to : from)];
+ transformAnimation.toValue =
+ [NSValue valueWithCATransform3D:(reverse ? from : to)];
+ transformAnimation.fillMode = kCAFillModeBoth;
+ transformAnimation.removedOnCompletion = NO;
+ [layer addAnimation:transformAnimation forKey:@"transform"];
+}
+
+- (void)animateFold:(BOOL)fold withCompletion:(ProceduralBlock)completion {
+ DCHECK(!_animatingFold);
+ const BOOL reversed = !fold;
+ _animatingFold = YES;
+ [self setUserInteractionEnabled:NO];
+ [CATransaction begin];
+ base::WeakNSObject<TabSwitcherTabStripPlaceholderView> weakSelf(self);
+ [CATransaction setCompletionBlock:^{
+ base::scoped_nsobject<TabSwitcherTabStripPlaceholderView> strongSelf(
+ [weakSelf retain]);
+ if (!strongSelf) {
+ if (completion)
+ completion();
+ return;
+ }
+ strongSelf.get()->_animatingFold = NO;
+ [strongSelf setUserInteractionEnabled:YES];
+ if (completion)
+ completion();
+ for (UIView* view in [strongSelf subviews]) {
+ [view.layer removeAnimationForKey:@"transform"];
+ }
+ }];
+ const CFTimeInterval currentTime =
+ [self.layer convertTime:CACurrentMediaTime() fromLayer:nil];
+ const NSInteger tabCount = [[self subviews] count];
+ const CFTimeInterval deltaTimeBetweenAnimations =
+ std::min((kFoldAnimationDuration - kTabFoldAnimationDuration) / tabCount,
+ kTabFoldAnimationDuration);
+ const BOOL isRTL = UseRTLLayout();
+ NSArray* orderedViews = [[self subviews]
+ sortedArrayUsingComparator:^(UIView* view1, UIView* view2) {
+ if (!isRTL) {
+ if (CGRectGetMinX(view1.frame) < CGRectGetMinX(view2.frame))
+ return NSOrderedDescending;
+ else
+ return NSOrderedAscending;
+ } else {
+ if (CGRectGetMaxX(view1.frame) > CGRectGetMaxX(view2.frame))
+ return NSOrderedDescending;
+ else
+ return NSOrderedAscending;
+ }
+ }];
+ // Fold all subviews one by one with a small delay and following the current
+ // UI layout direction.
+ int index = 0;
+ for (UIView* view in orderedViews) {
+ CATransform3D transform = CATransform3DConcat(
+ view.layer.transform,
+ CATransform3DMakeTranslation(0, view.bounds.size.height, 0));
+ [self addTransformAnimationToLayer:view.layer
+ duration:kTabFoldAnimationDuration
+ beginTime:currentTime +
+ index * deltaTimeBetweenAnimations
+ from:view.layer.transform
+ to:transform
+ reverse:reversed];
+ ++index;
+ }
+ [CATransaction commit];
+}
+
+@end

Powered by Google App Engine
This is Rietveld 408576698