Chromium Code Reviews| Index: ios/chrome/browser/ui/strip/strip_container_view_controller.mm |
| diff --git a/ios/chrome/browser/ui/strip/strip_container_view_controller.mm b/ios/chrome/browser/ui/strip/strip_container_view_controller.mm |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..d292cef68fb5430d18bcb32811e8370e8ddb0012 |
| --- /dev/null |
| +++ b/ios/chrome/browser/ui/strip/strip_container_view_controller.mm |
| @@ -0,0 +1,231 @@ |
| +// 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. |
| + |
| +// ====== New Architecture ===== |
| +// = This code is only used in the new iOS Chrome architecture. = |
| +// ============================================================================ |
| + |
| +#import "ios/chrome/browser/ui/strip/strip_container_view_controller.h" |
| + |
| +#import "ios/chrome/browser/ui/ui_types.h" |
| + |
| +#if !defined(__has_feature) || !__has_feature(objc_arc) |
| +#error "This file requires ARC support." |
| +#endif |
| + |
| +namespace { |
| +CGFloat kStripHeight = 200.0; |
| +} |
| + |
| +@interface StripContainerViewController () |
| + |
| +// Whichever view controller is at the top of the screen. This view controller |
| +// controls the status bar. |
| +@property(nonatomic, weak) UIViewController* topmostViewController; |
|
marq (ping after 24h)
2016/12/21 17:26:15
I don't think you need this if we aren't going to
edchin
2016/12/22 10:17:17
This container implementation accounts for when th
marq (ping after 24h)
2016/12/22 11:33:07
You are of course correct.
|
| + |
| +@property(nonatomic, strong) Constraints* contentConstraintsWithStrip; |
| +@property(nonatomic, strong) Constraints* contentConstraintsWithoutStrip; |
| +@property(nonatomic, strong) Constraints* stripConstraints; |
| + |
| +// Cache for forwarding methods to child view controllers. |
| +@property(nonatomic, assign) SEL actionToForward; |
| +@property(nonatomic, weak) UIResponder* forwardingTarget; |
| + |
| +@property(nonatomic, strong) NSLayoutConstraint* stripHeightConstraint; |
| + |
| +// Contained view controller utility methods. |
| +- (void)removeChildViewController:(UIViewController*)viewController; |
| + |
| +// Called after a new content view controller is set, but before |
| +// |-didMoveToParentViewController:| is called on that view controller. |
| +- (void)didAddContentViewController; |
| + |
| +// Called after a new strip view controller is set, but before |
| +// |-didMoveToParentViewController:| is called on that view controller. |
| +- (void)didAddContentViewController; |
|
marq (ping after 24h)
2016/12/21 17:26:15
-didAddStripViewController, right? Or is this erro
edchin
2016/12/22 10:17:17
Error in tab container as well. Will update that i
|
| + |
| +// Methods to populate the constraint properties. |
| +- (void)updateContentConstraintsWithStrip; |
| +- (void)updateContentConstraintsWithoutStrip; |
| +- (void)updateStripConstraints; |
| + |
| +@end |
| + |
| +@implementation StripContainerViewController |
| + |
| +@synthesize contentViewController = _contentViewController; |
| +@synthesize stripViewController = _stripViewController; |
| +@synthesize topmostViewController = _topmostViewController; |
| +@synthesize contentConstraintsWithStrip = _contentConstraintsWithStrip; |
| +@synthesize contentConstraintsWithoutStrip = _contentConstraintsWithoutStrip; |
| +@synthesize stripConstraints = _stripConstraints; |
| +@synthesize actionToForward = _actionToForward; |
| +@synthesize forwardingTarget = _forwardingTarget; |
| +@synthesize stripHeightConstraint = _stripHeightConstraint; |
| + |
| +#pragma mark - Public properties |
| + |
| +- (void)setContentViewController:(UIViewController*)contentViewController { |
| + if (self.contentViewController == contentViewController) |
| + return; |
| + |
| + // Remove the current content view controller, if any. |
| + [NSLayoutConstraint |
| + deactivateConstraints:self.contentConstraintsWithoutStrip]; |
| + [NSLayoutConstraint deactivateConstraints:self.contentConstraintsWithStrip]; |
| + [self removeChildViewController:self.contentViewController]; |
| + |
| + // Add the new content view controller. |
| + [self addChildViewController:contentViewController]; |
| + contentViewController.view.translatesAutoresizingMaskIntoConstraints = NO; |
| + [self.view addSubview:contentViewController.view]; |
| + _contentViewController = contentViewController; |
| + [self didAddContentViewController]; |
| + [self.view setNeedsUpdateConstraints]; |
| + [self.contentViewController didMoveToParentViewController:self]; |
| +} |
| + |
| +- (void)setStripViewController:(UIViewController*)stripViewController { |
| + if (self.stripViewController == stripViewController) |
| + return; |
| + |
| + // Remove the current strip view controller, if any. |
| + [NSLayoutConstraint deactivateConstraints:self.stripConstraints]; |
| + [NSLayoutConstraint deactivateConstraints:self.contentConstraintsWithStrip]; |
| + [self removeChildViewController:self.stripViewController]; |
| + |
| + // Add the new strip view controller. |
| + [self addChildViewController:stripViewController]; |
| + stripViewController.view.translatesAutoresizingMaskIntoConstraints = NO; |
| + [self.view addSubview:stripViewController.view]; |
| + _stripViewController = stripViewController; |
| + [self didAddStripViewController]; |
| + [self.view setNeedsUpdateConstraints]; |
| + [self.stripViewController didMoveToParentViewController:self]; |
| +} |
| + |
| +#pragma mark - UIViewController |
| + |
| +- (void)updateViewConstraints { |
| + if (self.stripViewController) { |
| + [NSLayoutConstraint activateConstraints:self.stripConstraints]; |
| + [NSLayoutConstraint activateConstraints:self.contentConstraintsWithStrip]; |
| + } else { |
| + [NSLayoutConstraint |
| + activateConstraints:self.contentConstraintsWithoutStrip]; |
| + } |
| + [super updateViewConstraints]; |
| +} |
| + |
| +- (UIViewController*)childViewControllerForStatusBarHidden { |
| + return self.topmostViewController; |
| +} |
| + |
| +- (UIViewController*)childViewControllerForStatusBarStyle { |
| + return self.topmostViewController; |
| +} |
| + |
| +#pragma mark - UIResponder |
| + |
| +// Before forwarding actions up the responder chain, give both contained |
| +// view controllers a chance to handle them. |
| +- (BOOL)canPerformAction:(SEL)action withSender:(id)sender { |
| + self.actionToForward = nullptr; |
| + self.forwardingTarget = nil; |
| + for (UIResponder* responder in |
| + @[ self.contentViewController, self.stripViewController ]) { |
| + if ([responder canPerformAction:action withSender:sender]) { |
| + self.actionToForward = action; |
| + self.forwardingTarget = responder; |
| + return YES; |
| + } |
| + } |
| + return [super canPerformAction:action withSender:sender]; |
| +} |
| + |
| +#pragma mark - NSObject method forwarding |
| + |
| +- (id)forwardingTargetForSelector:(SEL)aSelector { |
| + if (aSelector == self.actionToForward) { |
| + return self.forwardingTarget; |
| + } |
| + return nil; |
| +} |
| + |
| +#pragma mark - Private methods |
| + |
| +- (void)removeChildViewController:(UIViewController*)viewController { |
| + if (viewController.parentViewController != self) |
| + return; |
| + [viewController willMoveToParentViewController:nil]; |
| + [viewController.view removeFromSuperview]; |
| + [viewController removeFromParentViewController]; |
| +} |
| + |
| +- (void)didAddContentViewController { |
| + if (self.stripViewController) { |
| + [self updateContentConstraintsWithStrip]; |
| + } else { |
| + self.topmostViewController = self.contentViewController; |
| + [self updateContentConstraintsWithoutStrip]; |
| + } |
| + if (!self.stripViewController) { |
| + self.topmostViewController = self.contentViewController; |
| + } |
| +} |
| + |
| +- (void)didAddStripViewController { |
| + [self updateStripConstraints]; |
| + // If there's already a content view controller, update the constraints for |
| + // that, too. |
| + if (self.contentViewController) { |
| + [self updateContentConstraintsWithStrip]; |
| + } |
| + self.topmostViewController = self.stripViewController; |
| +} |
| + |
| +- (void)updateContentConstraintsWithoutStrip { |
| + UIView* contentView = self.contentViewController.view; |
| + self.contentConstraintsWithoutStrip = @[ |
| + [contentView.topAnchor constraintEqualToAnchor:self.view.topAnchor], |
| + [contentView.bottomAnchor constraintEqualToAnchor:self.view.bottomAnchor], |
| + [contentView.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor], |
| + [contentView.trailingAnchor |
| + constraintEqualToAnchor:self.view.trailingAnchor], |
| + ]; |
| +} |
| + |
| +- (void)updateContentConstraintsWithStrip { |
| + UIView* contentView = self.contentViewController.view; |
| + self.contentConstraintsWithStrip = @[ |
| + [contentView.topAnchor |
| + constraintEqualToAnchor:self.stripViewController.view.bottomAnchor], |
| + [contentView.bottomAnchor constraintEqualToAnchor:self.view.bottomAnchor], |
| + [contentView.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor], |
| + [contentView.trailingAnchor |
| + constraintEqualToAnchor:self.view.trailingAnchor], |
| + ]; |
| +} |
| + |
| +- (void)updateStripConstraints { |
| + UIView* stripView = self.stripViewController.view; |
| + self.stripHeightConstraint = |
| + [stripView.heightAnchor constraintEqualToConstant:0.0]; |
| + self.stripConstraints = @[ |
| + [stripView.topAnchor constraintEqualToAnchor:self.view.topAnchor], |
| + [stripView.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor], |
| + [stripView.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor], |
| + self.stripHeightConstraint, |
| + ]; |
| +} |
| + |
| +// Action for UIResponder chain that toggles visibility of tab strip. |
|
marq (ping after 24h)
2016/12/21 17:26:15
Nit: all actions are by definition using the respo
edchin
2016/12/22 10:17:17
Done.
|
| +- (void)toggleTabStrip:(id)sender { |
|
marq (ping after 24h)
2016/12/21 17:26:15
Add a ui/actions/tab_strip_actions.h file with a T
edchin
2016/12/22 10:17:17
Done.
|
| + self.stripHeightConstraint.constant = |
| + self.stripHeightConstraint.constant > 0 ? 0.0 : kStripHeight; |
| + [self.view setNeedsUpdateConstraints]; |
|
marq (ping after 24h)
2016/12/21 17:26:15
Is this needed? No constraints have been added or
edchin
2016/12/22 10:17:17
Done.
|
| + [self.view updateConstraintsIfNeeded]; |
| +} |
| + |
| +@end |