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

Side by Side Diff: ios/chrome/browser/ui/tab_switcher/tab_switcher_header_view.mm

Issue 2810193002: [ObjC ARC] Converts ios/chrome/browser/ui/tab_switcher:tab_switcher to ARC. (Closed)
Patch Set: comment Created 3 years, 7 months 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 unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #import "ios/chrome/browser/ui/tab_switcher/tab_switcher_header_view.h" 5 #import "ios/chrome/browser/ui/tab_switcher/tab_switcher_header_view.h"
6 6
7 #import "base/ios/weak_nsobject.h"
8 #include "base/logging.h" 7 #include "base/logging.h"
9 #include "base/mac/scoped_nsobject.h"
10 #include "base/metrics/user_metrics_action.h" 8 #include "base/metrics/user_metrics_action.h"
11 #import "ios/chrome/browser/ui/colors/MDCPalette+CrAdditions.h" 9 #import "ios/chrome/browser/ui/colors/MDCPalette+CrAdditions.h"
12 #include "ios/chrome/browser/ui/rtl_geometry.h" 10 #include "ios/chrome/browser/ui/rtl_geometry.h"
13 #import "ios/chrome/browser/ui/tab_switcher/tab_switcher_header_cell.h" 11 #import "ios/chrome/browser/ui/tab_switcher/tab_switcher_header_cell.h"
14 #import "ios/chrome/browser/ui/tab_switcher/tab_switcher_session_cell_data.h" 12 #import "ios/chrome/browser/ui/tab_switcher/tab_switcher_session_cell_data.h"
15 #import "ios/chrome/browser/ui/uikit_ui_util.h" 13 #import "ios/chrome/browser/ui/uikit_ui_util.h"
16 #include "ios/chrome/grit/ios_strings.h" 14 #include "ios/chrome/grit/ios_strings.h"
17 #import "ios/third_party/material_components_ios/src/components/Palettes/src/Mat erialPalettes.h" 15 #import "ios/third_party/material_components_ios/src/components/Palettes/src/Mat erialPalettes.h"
18 #include "ui/base/l10n/l10n_util.h" 16 #include "ui/base/l10n/l10n_util.h"
19 17
18 #if !defined(__has_feature) || !__has_feature(objc_arc)
19 #error "This file requires ARC support."
20 #endif
21
20 namespace { 22 namespace {
21 const CGFloat kCollectionViewTopMargin = 39.0; 23 const CGFloat kCollectionViewTopMargin = 39.0;
22 const CGFloat kCollectionViewHeight = 56.0; 24 const CGFloat kCollectionViewHeight = 56.0;
23 const CGFloat kDismissButtonWidth = 46.0; 25 const CGFloat kDismissButtonWidth = 46.0;
24 const CGFloat kDismissButtonHeight = 39.0; 26 const CGFloat kDismissButtonHeight = 39.0;
25 const CGFloat kCollectionViewCellWidth = 238; 27 const CGFloat kCollectionViewCellWidth = 238;
26 const CGFloat kActiveSpaceIndicatorHeight = 2; 28 const CGFloat kActiveSpaceIndicatorHeight = 2;
27 enum PanelSelectionChangeDirection { RIGHT, LEFT }; 29 enum PanelSelectionChangeDirection { RIGHT, LEFT };
28 } 30 }
29 31
30 @protocol AccessiblePanelSelectorDelegate 32 @protocol AccessiblePanelSelectorDelegate
31 // Scrolls to the panel in the direction |direction|, if possible. 33 // Scrolls to the panel in the direction |direction|, if possible.
32 - (void)moveToPanelInDirection:(PanelSelectionChangeDirection)direction; 34 - (void)moveToPanelInDirection:(PanelSelectionChangeDirection)direction;
33 @end 35 @end
34 36
35 // An invisible view that offers VoiceOver control of the panel selection 37 // An invisible view that offers VoiceOver control of the panel selection
36 // UICollectionView. 38 // UICollectionView.
37 // Notes: 39 // Notes:
38 // Directly subclassing UICollectionView resulted in a tons of unwanted 40 // Directly subclassing UICollectionView resulted in a tons of unwanted
39 // interactions with the cells. 41 // interactions with the cells.
40 // Subclassing UIAccessibilityElement instead of UIView is not possible if 42 // Subclassing UIAccessibilityElement instead of UIView is not possible if
41 // we want the accessibilityFrame to resize itself using autoresizing masks. 43 // we want the accessibilityFrame to resize itself using autoresizing masks.
42 @interface AccessiblePanelSelectorView : UIView { 44 @interface AccessiblePanelSelectorView : UIView {
43 // The delegate which receives actions. 45 // The delegate which receives actions.
44 base::WeakNSProtocol<id<AccessiblePanelSelectorDelegate>> _delegate; 46 __weak id<AccessiblePanelSelectorDelegate> _delegate;
45 } 47 }
46 - (void)setDelegate:(id<AccessiblePanelSelectorDelegate>)delegate; 48 - (void)setDelegate:(id<AccessiblePanelSelectorDelegate>)delegate;
47 @end 49 @end
48 50
49 @implementation AccessiblePanelSelectorView 51 @implementation AccessiblePanelSelectorView
50 52
51 - (void)setDelegate:(id<AccessiblePanelSelectorDelegate>)delegate { 53 - (void)setDelegate:(id<AccessiblePanelSelectorDelegate>)delegate {
52 _delegate.reset(delegate); 54 _delegate = delegate;
53 } 55 }
54 56
55 - (UIAccessibilityTraits)accessibilityTraits { 57 - (UIAccessibilityTraits)accessibilityTraits {
56 return [super accessibilityTraits] | UIAccessibilityTraitAdjustable | 58 return [super accessibilityTraits] | UIAccessibilityTraitAdjustable |
57 UIAccessibilityTraitCausesPageTurn; 59 UIAccessibilityTraitCausesPageTurn;
58 } 60 }
59 61
60 - (BOOL)isAccessibilityElement { 62 - (BOOL)isAccessibilityElement {
61 return YES; 63 return YES;
62 } 64 }
63 65
64 - (void)accessibilityIncrement { 66 - (void)accessibilityIncrement {
65 [_delegate moveToPanelInDirection:RIGHT]; 67 [_delegate moveToPanelInDirection:RIGHT];
66 } 68 }
67 69
68 - (void)accessibilityDecrement { 70 - (void)accessibilityDecrement {
69 [_delegate moveToPanelInDirection:LEFT]; 71 [_delegate moveToPanelInDirection:LEFT];
70 } 72 }
71 73
72 @end 74 @end
73 75
74 @interface TabSwitcherHeaderView ()<UICollectionViewDataSource, 76 @interface TabSwitcherHeaderView ()<UICollectionViewDataSource,
75 UICollectionViewDelegate, 77 UICollectionViewDelegate,
76 AccessiblePanelSelectorDelegate> { 78 AccessiblePanelSelectorDelegate> {
77 base::scoped_nsobject<UICollectionViewFlowLayout> _flowLayout; 79 UICollectionViewFlowLayout* _flowLayout;
78 base::scoped_nsobject<UICollectionView> _collectionView; 80 UICollectionView* _collectionView;
79 base::scoped_nsobject<AccessiblePanelSelectorView> _accessibilityView; 81 AccessiblePanelSelectorView* _accessibilityView;
80 base::scoped_nsobject<UIButton> _dismissButton; 82 UIButton* _dismissButton;
81 base::scoped_nsobject<UIView> _activeSpaceIndicatorView; 83 UIView* _activeSpaceIndicatorView;
82 84
83 BOOL _performingUpdate; 85 BOOL _performingUpdate;
84 } 86 }
85 87
86 // Loads and initializes subviews. 88 // Loads and initializes subviews.
87 - (void)loadSubviews; 89 - (void)loadSubviews;
88 // Performs layout of the collection view. 90 // Performs layout of the collection view.
89 - (void)layoutCollectionView; 91 - (void)layoutCollectionView;
90 92
91 @end 93 @end
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
126 } 128 }
127 129
128 - (void)performUpdate:(void (^)(TabSwitcherHeaderView* headerView))updateBlock { 130 - (void)performUpdate:(void (^)(TabSwitcherHeaderView* headerView))updateBlock {
129 [self performUpdate:updateBlock completion:nil]; 131 [self performUpdate:updateBlock completion:nil];
130 } 132 }
131 133
132 - (void)performUpdate:(void (^)(TabSwitcherHeaderView* headerView))updateBlock 134 - (void)performUpdate:(void (^)(TabSwitcherHeaderView* headerView))updateBlock
133 completion:(ProceduralBlock)completion { 135 completion:(ProceduralBlock)completion {
134 DCHECK(updateBlock); 136 DCHECK(updateBlock);
135 137
136 __block TabSwitcherHeaderView* weakSelf = self; 138 __weak TabSwitcherHeaderView* weakSelf = self;
137 [_collectionView performBatchUpdates:^{ 139 [_collectionView performBatchUpdates:^{
138 if (!weakSelf) 140 TabSwitcherHeaderView* strongSelf = weakSelf;
141 if (!strongSelf)
139 return; 142 return;
140 weakSelf->_performingUpdate = YES; 143 strongSelf->_performingUpdate = YES;
141 updateBlock(weakSelf); 144 updateBlock(strongSelf);
142 weakSelf->_performingUpdate = NO; 145 strongSelf->_performingUpdate = NO;
143 } 146 }
144 completion:^(BOOL finished) { 147 completion:^(BOOL finished) {
145 // Reestablish selection after the update. 148 // Reestablish selection after the update.
146 const NSInteger selectedPanelIndex = 149 const NSInteger selectedPanelIndex =
147 [[weakSelf delegate] tabSwitcherHeaderViewSelectedPanelIndex]; 150 [[weakSelf delegate] tabSwitcherHeaderViewSelectedPanelIndex];
148 if (selectedPanelIndex != NSNotFound) 151 if (selectedPanelIndex != NSNotFound)
149 [weakSelf selectItemAtIndex:selectedPanelIndex]; 152 [weakSelf selectItemAtIndex:selectedPanelIndex];
150 if (completion) 153 if (completion)
151 completion(); 154 completion();
152 }]; 155 }];
153 } 156 }
154 157
155 - (void)insertSessionsAtIndexes:(NSArray*)indexes { 158 - (void)insertSessionsAtIndexes:(NSArray*)indexes {
156 DCHECK(_performingUpdate); 159 DCHECK(_performingUpdate);
157 [_collectionView 160 [_collectionView
158 insertItemsAtIndexPaths:[self indexPathArrayWithIndexes:indexes]]; 161 insertItemsAtIndexPaths:[self indexPathArrayWithIndexes:indexes]];
159 } 162 }
160 163
161 - (void)removeSessionsAtIndexes:(NSArray*)indexes { 164 - (void)removeSessionsAtIndexes:(NSArray*)indexes {
162 DCHECK(_performingUpdate); 165 DCHECK(_performingUpdate);
163 [_collectionView 166 [_collectionView
164 deleteItemsAtIndexPaths:[self indexPathArrayWithIndexes:indexes]]; 167 deleteItemsAtIndexPaths:[self indexPathArrayWithIndexes:indexes]];
165 } 168 }
166 169
167 - (UIView*)dismissButton { 170 - (UIView*)dismissButton {
168 return _dismissButton.get(); 171 return _dismissButton;
169 } 172 }
170 173
171 #pragma mark - Private 174 #pragma mark - Private
172 175
173 - (NSInteger)selectedIndex { 176 - (NSInteger)selectedIndex {
174 NSInteger selectedIndex = NSNotFound; 177 NSInteger selectedIndex = NSNotFound;
175 NSArray* selectedIndexPaths = [_collectionView indexPathsForSelectedItems]; 178 NSArray* selectedIndexPaths = [_collectionView indexPathsForSelectedItems];
176 if (selectedIndexPaths.count) { 179 if (selectedIndexPaths.count) {
177 NSIndexPath* selectedIndexPath = selectedIndexPaths[0]; 180 NSIndexPath* selectedIndexPath = selectedIndexPaths[0];
178 selectedIndex = selectedIndexPath.item; 181 selectedIndex = selectedIndexPath.item;
(...skipping 16 matching lines...) Expand all
195 const CGRect cellRect = CGRectMake( 198 const CGRect cellRect = CGRectMake(
196 [self leftToRightIndexForFlowLayoutIndex:index] * 199 [self leftToRightIndexForFlowLayoutIndex:index] *
197 kCollectionViewCellWidth, 200 kCollectionViewCellWidth,
198 0, kCollectionViewCellWidth, [_collectionView bounds].size.height); 201 0, kCollectionViewCellWidth, [_collectionView bounds].size.height);
199 [_collectionView scrollRectToVisible:cellRect animated:animated]; 202 [_collectionView scrollRectToVisible:cellRect animated:animated];
200 [self layoutActiveSpaceIndicatorAnimated:animated]; 203 [self layoutActiveSpaceIndicatorAnimated:animated];
201 } 204 }
202 205
203 - (NSArray*)indexPathArrayWithIndexes:(NSArray*)indexes { 206 - (NSArray*)indexPathArrayWithIndexes:(NSArray*)indexes {
204 NSMutableArray* array = 207 NSMutableArray* array =
205 [[[NSMutableArray alloc] initWithCapacity:indexes.count] autorelease]; 208 [[NSMutableArray alloc] initWithCapacity:indexes.count];
206 for (NSNumber* index in indexes) { 209 for (NSNumber* index in indexes) {
207 [array 210 [array
208 addObject:[NSIndexPath indexPathForItem:[index intValue] inSection:0]]; 211 addObject:[NSIndexPath indexPathForItem:[index intValue] inSection:0]];
209 } 212 }
210 return array; 213 return array;
211 } 214 }
212 215
213 - (void)loadSubviews { 216 - (void)loadSubviews {
214 base::scoped_nsobject<UICollectionViewFlowLayout> flowLayout( 217 UICollectionViewFlowLayout* flowLayout =
215 [[UICollectionViewFlowLayout alloc] init]); 218 [[UICollectionViewFlowLayout alloc] init];
216 [flowLayout setMinimumLineSpacing:0]; 219 [flowLayout setMinimumLineSpacing:0];
217 [flowLayout setMinimumInteritemSpacing:0]; 220 [flowLayout setMinimumInteritemSpacing:0];
218 const CGSize cellSize = 221 const CGSize cellSize =
219 CGSizeMake(kCollectionViewCellWidth, kCollectionViewHeight); 222 CGSizeMake(kCollectionViewCellWidth, kCollectionViewHeight);
220 [flowLayout setItemSize:cellSize]; 223 [flowLayout setItemSize:cellSize];
221 [flowLayout setScrollDirection:UICollectionViewScrollDirectionHorizontal]; 224 [flowLayout setScrollDirection:UICollectionViewScrollDirectionHorizontal];
222 _flowLayout = flowLayout; 225 _flowLayout = flowLayout;
223 226
224 _collectionView.reset([[UICollectionView alloc] 227 _collectionView =
225 initWithFrame:[self collectionViewFrame] 228 [[UICollectionView alloc] initWithFrame:[self collectionViewFrame]
226 collectionViewLayout:flowLayout]); 229 collectionViewLayout:flowLayout];
227 [_collectionView setDelegate:self]; 230 [_collectionView setDelegate:self];
228 [_collectionView setDataSource:self]; 231 [_collectionView setDataSource:self];
229 [_collectionView registerClass:[TabSwitcherHeaderCell class] 232 [_collectionView registerClass:[TabSwitcherHeaderCell class]
230 forCellWithReuseIdentifier:[TabSwitcherHeaderCell identifier]]; 233 forCellWithReuseIdentifier:[TabSwitcherHeaderCell identifier]];
231 [_collectionView setShowsVerticalScrollIndicator:NO]; 234 [_collectionView setShowsVerticalScrollIndicator:NO];
232 [_collectionView setShowsHorizontalScrollIndicator:NO]; 235 [_collectionView setShowsHorizontalScrollIndicator:NO];
233 [_collectionView setBackgroundColor:[[MDCPalette greyPalette] tint900]]; 236 [_collectionView setBackgroundColor:[[MDCPalette greyPalette] tint900]];
234 [_collectionView setAllowsMultipleSelection:NO]; 237 [_collectionView setAllowsMultipleSelection:NO];
235 [_collectionView setAllowsSelection:YES]; 238 [_collectionView setAllowsSelection:YES];
236 [_collectionView setIsAccessibilityElement:NO]; 239 [_collectionView setIsAccessibilityElement:NO];
237 [_collectionView setAccessibilityElementsHidden:YES]; 240 [_collectionView setAccessibilityElementsHidden:YES];
238 [self addSubview:_collectionView]; 241 [self addSubview:_collectionView];
239 242
240 _accessibilityView.reset([[AccessiblePanelSelectorView alloc] 243 _accessibilityView = [[AccessiblePanelSelectorView alloc]
241 initWithFrame:[self collectionViewFrame]]); 244 initWithFrame:[self collectionViewFrame]];
242 [_accessibilityView 245 [_accessibilityView
243 setAutoresizingMask:UIViewAutoresizingFlexibleBottomMargin | 246 setAutoresizingMask:UIViewAutoresizingFlexibleBottomMargin |
244 UIViewAutoresizingFlexibleWidth]; 247 UIViewAutoresizingFlexibleWidth];
245 [_accessibilityView setDelegate:self]; 248 [_accessibilityView setDelegate:self];
246 [_accessibilityView setUserInteractionEnabled:NO]; 249 [_accessibilityView setUserInteractionEnabled:NO];
247 [self addSubview:_accessibilityView]; 250 [self addSubview:_accessibilityView];
248 251
249 _dismissButton.reset([[UIButton alloc] initWithFrame:CGRectZero]); 252 _dismissButton = [[UIButton alloc] initWithFrame:CGRectZero];
250 UIImage* dismissImage = 253 UIImage* dismissImage =
251 [UIImage imageNamed:@"tabswitcher_tab_switcher_button"]; 254 [UIImage imageNamed:@"tabswitcher_tab_switcher_button"];
252 dismissImage = 255 dismissImage =
253 [dismissImage imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]; 256 [dismissImage imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
254 [_dismissButton setContentMode:UIViewContentModeCenter]; 257 [_dismissButton setContentMode:UIViewContentModeCenter];
255 [_dismissButton setBackgroundColor:[UIColor clearColor]]; 258 [_dismissButton setBackgroundColor:[UIColor clearColor]];
256 [_dismissButton setTintColor:[UIColor whiteColor]]; 259 [_dismissButton setTintColor:[UIColor whiteColor]];
257 [_dismissButton setImage:dismissImage forState:UIControlStateNormal]; 260 [_dismissButton setImage:dismissImage forState:UIControlStateNormal];
258 [_dismissButton 261 [_dismissButton
259 setAccessibilityLabel:l10n_util::GetNSString( 262 setAccessibilityLabel:l10n_util::GetNSString(
260 IDS_IOS_TAB_STRIP_LEAVE_TAB_SWITCHER)]; 263 IDS_IOS_TAB_STRIP_LEAVE_TAB_SWITCHER)];
261 264
262 [_dismissButton addTarget:self 265 [_dismissButton addTarget:self
263 action:@selector(dismissButtonTouchUpInside:) 266 action:@selector(dismissButtonTouchUpInside:)
264 forControlEvents:UIControlEventTouchUpInside]; 267 forControlEvents:UIControlEventTouchUpInside];
265 [_dismissButton setTranslatesAutoresizingMaskIntoConstraints:NO]; 268 [_dismissButton setTranslatesAutoresizingMaskIntoConstraints:NO];
266 [self addSubview:_dismissButton]; 269 [self addSubview:_dismissButton];
267 270
268 NSArray* constraints = @[ 271 NSArray* constraints = @[
269 @"V:|-0-[dismissButton(==buttonHeight)]", 272 @"V:|-0-[dismissButton(==buttonHeight)]",
270 @"H:[dismissButton(==buttonWidth)]-0-|", 273 @"H:[dismissButton(==buttonWidth)]-0-|",
271 ]; 274 ];
272 NSDictionary* viewsDictionary = @{ 275 NSDictionary* viewsDictionary = @{
273 @"dismissButton" : _dismissButton.get(), 276 @"dismissButton" : _dismissButton,
274 }; 277 };
275 NSDictionary* metrics = @{ 278 NSDictionary* metrics = @{
276 @"buttonHeight" : @(kDismissButtonHeight), 279 @"buttonHeight" : @(kDismissButtonHeight),
277 @"buttonWidth" : @(kDismissButtonWidth), 280 @"buttonWidth" : @(kDismissButtonWidth),
278 }; 281 };
279 ApplyVisualConstraintsWithMetricsAndOptions( 282 ApplyVisualConstraintsWithMetricsAndOptions(
280 constraints, viewsDictionary, metrics, LayoutOptionForRTLSupport(), self); 283 constraints, viewsDictionary, metrics, LayoutOptionForRTLSupport(), self);
281 284
282 base::scoped_nsobject<UIView> activeSpaceIndicatorView( 285 UIView* activeSpaceIndicatorView = [[UIView alloc] initWithFrame:CGRectZero];
283 [[UIView alloc] initWithFrame:CGRectZero]);
284 [activeSpaceIndicatorView 286 [activeSpaceIndicatorView
285 setBackgroundColor:[[MDCPalette cr_bluePalette] tint500]]; 287 setBackgroundColor:[[MDCPalette cr_bluePalette] tint500]];
286 [activeSpaceIndicatorView 288 [activeSpaceIndicatorView
287 setFrame:CGRectMake( 289 setFrame:CGRectMake(
288 0, self.bounds.size.height - kActiveSpaceIndicatorHeight, 290 0, self.bounds.size.height - kActiveSpaceIndicatorHeight,
289 kCollectionViewCellWidth, kActiveSpaceIndicatorHeight)]; 291 kCollectionViewCellWidth, kActiveSpaceIndicatorHeight)];
290 [self addSubview:activeSpaceIndicatorView]; 292 [self addSubview:activeSpaceIndicatorView];
291 _activeSpaceIndicatorView = activeSpaceIndicatorView; 293 _activeSpaceIndicatorView = activeSpaceIndicatorView;
292 } 294 }
293 295
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
387 [[self delegate] tabSwitcherHeaderViewDidSelectSessionAtIndex:indexPath.item]; 389 [[self delegate] tabSwitcherHeaderViewDidSelectSessionAtIndex:indexPath.item];
388 } 390 }
389 391
390 #pragma mark - UIScrollViewDelegate 392 #pragma mark - UIScrollViewDelegate
391 393
392 - (void)scrollViewDidScroll:(UIScrollView*)scrollView { 394 - (void)scrollViewDidScroll:(UIScrollView*)scrollView {
393 [self layoutActiveSpaceIndicatorAnimated:NO]; 395 [self layoutActiveSpaceIndicatorAnimated:NO];
394 } 396 }
395 397
396 @end 398 @end
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698