Commit 8359e507 authored by edchin's avatar edchin Committed by Commit bot

Simple strip container that can reveal/hide tab strip.

The simple strip container is WIP and this CL has only
minimal functionality. This CL also showcases this
strip container in Showcase.

BUG=none.

Review-Url: https://codereview.chromium.org/2594023002
Cr-Commit-Position: refs/heads/master@{#440853}
parent c5d4f1b1
......@@ -6,6 +6,7 @@ source_set("actions") {
sources = [
"settings_actions.h",
"tab_grid_actions.h",
"tab_strip_actions.h",
"tools_menu_actions.h",
]
......
// 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. =
// ============================================================================
#ifndef IOS_CHROME_BROWSER_UI_ACTIONS_TAB_STRIP_ACTIONS_H_
#define IOS_CHROME_BROWSER_UI_ACTIONS_TAB_STRIP_ACTIONS_H_
#import <Foundation/Foundation.h>
// Target/Action methods relating to the tab strip.
@protocol TabStripActions
@optional
// Reveals or hides the tab strip.
- (void)toggleTabStrip:(id)sender;
@end
#endif // IOS_CHROME_BROWSER_UI_ACTIONS_TAB_STRIP_ACTIONS_H_
# 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.
source_set("strip_ui") {
sources = [
"strip_container_view_controller.h",
"strip_container_view_controller.mm",
]
deps = [
"//ios/chrome/browser/ui:ui_clean_skeleton",
"//ios/chrome/browser/ui/actions",
]
libs = [ "UIKit.framework" ]
configs += [ "//build/config/compiler:enable_arc" ]
}
// 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. =
// ============================================================================
#ifndef IOS_CHROME_BROWSER_UI_STRIP_STRIP_CONTAINER_VIEW_CONTROLLER_H_
#define IOS_CHROME_BROWSER_UI_STRIP_STRIP_CONTAINER_VIEW_CONTROLLER_H_
#import <UIKit/UIKit.h>
// Base class for a view controller that contains a content view (generally a
// web view with toolbar, but nothing in this class assumes that) and a strip
// view, each managed by their own view controllers.
@interface StripContainerViewController : UIViewController
// View controller showing the main content. If there is no strip view
// controller set, the contents of this view controller will fill all of the
// strip container's view.
@property(nonatomic, strong) UIViewController* contentViewController;
// View controller showing the strip. It will be of a fixed
// height (determined internally by the strip container), but will span the
// width of the tab.
@property(nonatomic, strong) UIViewController* stripViewController;
@end
#endif // IOS_CHROME_BROWSER_UI_STRIP_STRIP_CONTAINER_VIEW_CONTROLLER_H_
// 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"
#import "ios/chrome/browser/ui/actions/tab_strip_actions.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
namespace {
CGFloat kStripHeight = 200.0;
}
@interface StripContainerViewController ()<TabStripActions>
// Whichever view controller is at the top of the screen. This view controller
// controls the status bar.
@property(nonatomic, weak) UIViewController* topmostViewController;
@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)didAddStripViewController;
// 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 - TabStripActions
// Action to toggle visibility of tab strip.
- (void)toggleTabStrip:(id)sender {
self.stripHeightConstraint.constant =
self.stripHeightConstraint.constant > 0 ? 0.0 : kStripHeight;
}
#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];
}
}
- (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,
];
}
@end
......@@ -27,6 +27,7 @@ group("features") {
deps = [
"//ios/chrome/browser/ui/tools:tools_ui",
"//ios/showcase/settings",
"//ios/showcase/strip",
"//ios/showcase/tab_grid",
"//ios/showcase/uikit_table_view_cell",
]
......
......@@ -36,6 +36,11 @@
showcase::kClassForInstantiationKey : @"SCTabGridCoordinator",
showcase::kUseCaseKey : @"Tab grid",
},
@{
showcase::kClassForDisplayKey : @"StripContainerViewController",
showcase::kClassForInstantiationKey : @"SCStripCoordinator",
showcase::kUseCaseKey : @"Tab strip container",
},
];
}
......
# 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.
source_set("strip") {
sources = [
"sc_strip_coordinator.h",
"sc_strip_coordinator.mm",
]
deps = [
"//ios/chrome/browser/ui/actions",
"//ios/chrome/browser/ui/strip:strip_ui",
"//ios/showcase/common",
]
libs = [ "UIKit.framework" ]
configs += [ "//build/config/compiler:enable_arc" ]
}
// 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.
#ifndef IOS_SHOWCASE_STRIP_SC_STRIP_COORDINATOR_H_
#define IOS_SHOWCASE_STRIP_SC_STRIP_COORDINATOR_H_
#import <UIKit/UIKit.h>
#import "ios/showcase/common/coordinator.h"
@interface SCStripCoordinator : NSObject<Coordinator>
// Redefined to be a UINavigationController.
@property(nonatomic, weak) UINavigationController* baseViewController;
@end
#endif // IOS_SHOWCASE_STRIP_SC_STRIP_COORDINATOR_H_
// 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/showcase/strip/sc_strip_coordinator.h"
#import "ios/chrome/browser/ui/actions/tab_strip_actions.h"
#import "ios/chrome/browser/ui/strip/strip_container_view_controller.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
@interface SCStripCoordinator ()
@property(nonatomic, strong) StripContainerViewController* viewController;
@end
@implementation SCStripCoordinator
@synthesize baseViewController = _baseViewController;
@synthesize viewController = _viewController;
- (void)start {
UIViewController* blackViewController = [[UIViewController alloc] init];
blackViewController.view.backgroundColor = [UIColor blackColor];
UIViewController* greenViewController =
[self viewControllerWithButtonTitle:@"toggleStrip"
action:@selector(toggleTabStrip:)];
greenViewController.view.backgroundColor = [UIColor greenColor];
self.viewController = [[StripContainerViewController alloc] init];
self.viewController.title = @"Tab strip container";
self.viewController.stripViewController = blackViewController;
self.viewController.contentViewController = greenViewController;
self.baseViewController.navigationBar.translucent = NO;
[self.baseViewController pushViewController:self.viewController animated:YES];
}
- (UIViewController*)viewControllerWithButtonTitle:(NSString*)title
action:(SEL)action {
UIViewController* viewController = [[UIViewController alloc] init];
UIButton* button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[button setFrame:CGRectMake(10, 10, 80, 50)];
[button setTitle:title forState:UIControlStateNormal];
[viewController.view addSubview:button];
[button addTarget:nil
action:action
forControlEvents:UIControlEventTouchUpInside];
return viewController;
}
@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