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 |