OLD | NEW |
(Empty) | |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 // ====== New Architecture ===== |
| 6 // = This code is only used in the new iOS Chrome architecture. = |
| 7 // ============================================================================ |
| 8 |
| 9 #import "ios/chrome/browser/ui/strip/strip_container_view_controller.h" |
| 10 |
| 11 #import "ios/chrome/browser/ui/ui_types.h" |
| 12 #import "ios/chrome/browser/ui/actions/tab_strip_actions.h" |
| 13 |
| 14 #if !defined(__has_feature) || !__has_feature(objc_arc) |
| 15 #error "This file requires ARC support." |
| 16 #endif |
| 17 |
| 18 namespace { |
| 19 CGFloat kStripHeight = 200.0; |
| 20 } |
| 21 |
| 22 @interface StripContainerViewController ()<TabStripActions> |
| 23 |
| 24 // Whichever view controller is at the top of the screen. This view controller |
| 25 // controls the status bar. |
| 26 @property(nonatomic, weak) UIViewController* topmostViewController; |
| 27 |
| 28 @property(nonatomic, strong) Constraints* contentConstraintsWithStrip; |
| 29 @property(nonatomic, strong) Constraints* contentConstraintsWithoutStrip; |
| 30 @property(nonatomic, strong) Constraints* stripConstraints; |
| 31 |
| 32 // Cache for forwarding methods to child view controllers. |
| 33 @property(nonatomic, assign) SEL actionToForward; |
| 34 @property(nonatomic, weak) UIResponder* forwardingTarget; |
| 35 |
| 36 @property(nonatomic, strong) NSLayoutConstraint* stripHeightConstraint; |
| 37 |
| 38 // Contained view controller utility methods. |
| 39 - (void)removeChildViewController:(UIViewController*)viewController; |
| 40 |
| 41 // Called after a new content view controller is set, but before |
| 42 // |-didMoveToParentViewController:| is called on that view controller. |
| 43 - (void)didAddContentViewController; |
| 44 |
| 45 // Called after a new strip view controller is set, but before |
| 46 // |-didMoveToParentViewController:| is called on that view controller. |
| 47 - (void)didAddStripViewController; |
| 48 |
| 49 // Methods to populate the constraint properties. |
| 50 - (void)updateContentConstraintsWithStrip; |
| 51 - (void)updateContentConstraintsWithoutStrip; |
| 52 - (void)updateStripConstraints; |
| 53 |
| 54 @end |
| 55 |
| 56 @implementation StripContainerViewController |
| 57 |
| 58 @synthesize contentViewController = _contentViewController; |
| 59 @synthesize stripViewController = _stripViewController; |
| 60 @synthesize topmostViewController = _topmostViewController; |
| 61 @synthesize contentConstraintsWithStrip = _contentConstraintsWithStrip; |
| 62 @synthesize contentConstraintsWithoutStrip = _contentConstraintsWithoutStrip; |
| 63 @synthesize stripConstraints = _stripConstraints; |
| 64 @synthesize actionToForward = _actionToForward; |
| 65 @synthesize forwardingTarget = _forwardingTarget; |
| 66 @synthesize stripHeightConstraint = _stripHeightConstraint; |
| 67 |
| 68 #pragma mark - Public properties |
| 69 |
| 70 - (void)setContentViewController:(UIViewController*)contentViewController { |
| 71 if (self.contentViewController == contentViewController) |
| 72 return; |
| 73 |
| 74 // Remove the current content view controller, if any. |
| 75 [NSLayoutConstraint |
| 76 deactivateConstraints:self.contentConstraintsWithoutStrip]; |
| 77 [NSLayoutConstraint deactivateConstraints:self.contentConstraintsWithStrip]; |
| 78 [self removeChildViewController:self.contentViewController]; |
| 79 |
| 80 // Add the new content view controller. |
| 81 [self addChildViewController:contentViewController]; |
| 82 contentViewController.view.translatesAutoresizingMaskIntoConstraints = NO; |
| 83 [self.view addSubview:contentViewController.view]; |
| 84 _contentViewController = contentViewController; |
| 85 [self didAddContentViewController]; |
| 86 [self.view setNeedsUpdateConstraints]; |
| 87 [self.contentViewController didMoveToParentViewController:self]; |
| 88 } |
| 89 |
| 90 - (void)setStripViewController:(UIViewController*)stripViewController { |
| 91 if (self.stripViewController == stripViewController) |
| 92 return; |
| 93 |
| 94 // Remove the current strip view controller, if any. |
| 95 [NSLayoutConstraint deactivateConstraints:self.stripConstraints]; |
| 96 [NSLayoutConstraint deactivateConstraints:self.contentConstraintsWithStrip]; |
| 97 [self removeChildViewController:self.stripViewController]; |
| 98 |
| 99 // Add the new strip view controller. |
| 100 [self addChildViewController:stripViewController]; |
| 101 stripViewController.view.translatesAutoresizingMaskIntoConstraints = NO; |
| 102 [self.view addSubview:stripViewController.view]; |
| 103 _stripViewController = stripViewController; |
| 104 [self didAddStripViewController]; |
| 105 [self.view setNeedsUpdateConstraints]; |
| 106 [self.stripViewController didMoveToParentViewController:self]; |
| 107 } |
| 108 |
| 109 #pragma mark - UIViewController |
| 110 |
| 111 - (void)updateViewConstraints { |
| 112 if (self.stripViewController) { |
| 113 [NSLayoutConstraint activateConstraints:self.stripConstraints]; |
| 114 [NSLayoutConstraint activateConstraints:self.contentConstraintsWithStrip]; |
| 115 } else { |
| 116 [NSLayoutConstraint |
| 117 activateConstraints:self.contentConstraintsWithoutStrip]; |
| 118 } |
| 119 [super updateViewConstraints]; |
| 120 } |
| 121 |
| 122 - (UIViewController*)childViewControllerForStatusBarHidden { |
| 123 return self.topmostViewController; |
| 124 } |
| 125 |
| 126 - (UIViewController*)childViewControllerForStatusBarStyle { |
| 127 return self.topmostViewController; |
| 128 } |
| 129 |
| 130 #pragma mark - UIResponder |
| 131 |
| 132 // Before forwarding actions up the responder chain, give both contained |
| 133 // view controllers a chance to handle them. |
| 134 - (BOOL)canPerformAction:(SEL)action withSender:(id)sender { |
| 135 self.actionToForward = nullptr; |
| 136 self.forwardingTarget = nil; |
| 137 for (UIResponder* responder in |
| 138 @[ self.contentViewController, self.stripViewController ]) { |
| 139 if ([responder canPerformAction:action withSender:sender]) { |
| 140 self.actionToForward = action; |
| 141 self.forwardingTarget = responder; |
| 142 return YES; |
| 143 } |
| 144 } |
| 145 return [super canPerformAction:action withSender:sender]; |
| 146 } |
| 147 |
| 148 #pragma mark - NSObject method forwarding |
| 149 |
| 150 - (id)forwardingTargetForSelector:(SEL)aSelector { |
| 151 if (aSelector == self.actionToForward) { |
| 152 return self.forwardingTarget; |
| 153 } |
| 154 return nil; |
| 155 } |
| 156 |
| 157 #pragma mark - TabStripActions |
| 158 |
| 159 // Action to toggle visibility of tab strip. |
| 160 - (void)toggleTabStrip:(id)sender { |
| 161 self.stripHeightConstraint.constant = |
| 162 self.stripHeightConstraint.constant > 0 ? 0.0 : kStripHeight; |
| 163 } |
| 164 |
| 165 #pragma mark - Private methods |
| 166 |
| 167 - (void)removeChildViewController:(UIViewController*)viewController { |
| 168 if (viewController.parentViewController != self) |
| 169 return; |
| 170 [viewController willMoveToParentViewController:nil]; |
| 171 [viewController.view removeFromSuperview]; |
| 172 [viewController removeFromParentViewController]; |
| 173 } |
| 174 |
| 175 - (void)didAddContentViewController { |
| 176 if (self.stripViewController) { |
| 177 [self updateContentConstraintsWithStrip]; |
| 178 } else { |
| 179 self.topmostViewController = self.contentViewController; |
| 180 [self updateContentConstraintsWithoutStrip]; |
| 181 } |
| 182 } |
| 183 |
| 184 - (void)didAddStripViewController { |
| 185 [self updateStripConstraints]; |
| 186 // If there's already a content view controller, update the constraints for |
| 187 // that, too. |
| 188 if (self.contentViewController) { |
| 189 [self updateContentConstraintsWithStrip]; |
| 190 } |
| 191 self.topmostViewController = self.stripViewController; |
| 192 } |
| 193 |
| 194 - (void)updateContentConstraintsWithoutStrip { |
| 195 UIView* contentView = self.contentViewController.view; |
| 196 self.contentConstraintsWithoutStrip = @[ |
| 197 [contentView.topAnchor constraintEqualToAnchor:self.view.topAnchor], |
| 198 [contentView.bottomAnchor constraintEqualToAnchor:self.view.bottomAnchor], |
| 199 [contentView.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor], |
| 200 [contentView.trailingAnchor |
| 201 constraintEqualToAnchor:self.view.trailingAnchor], |
| 202 ]; |
| 203 } |
| 204 |
| 205 - (void)updateContentConstraintsWithStrip { |
| 206 UIView* contentView = self.contentViewController.view; |
| 207 self.contentConstraintsWithStrip = @[ |
| 208 [contentView.topAnchor |
| 209 constraintEqualToAnchor:self.stripViewController.view.bottomAnchor], |
| 210 [contentView.bottomAnchor constraintEqualToAnchor:self.view.bottomAnchor], |
| 211 [contentView.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor], |
| 212 [contentView.trailingAnchor |
| 213 constraintEqualToAnchor:self.view.trailingAnchor], |
| 214 ]; |
| 215 } |
| 216 |
| 217 - (void)updateStripConstraints { |
| 218 UIView* stripView = self.stripViewController.view; |
| 219 self.stripHeightConstraint = |
| 220 [stripView.heightAnchor constraintEqualToConstant:0.0]; |
| 221 self.stripConstraints = @[ |
| 222 [stripView.topAnchor constraintEqualToAnchor:self.view.topAnchor], |
| 223 [stripView.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor], |
| 224 [stripView.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor], |
| 225 self.stripHeightConstraint, |
| 226 ]; |
| 227 } |
| 228 |
| 229 @end |
OLD | NEW |