OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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/ntp/google_landing_controller.h" | 5 #import "ios/chrome/browser/ui/ntp/google_landing_controller.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/mac/foundation_util.h" | 9 #include "base/mac/foundation_util.h" |
10 #include "base/metrics/user_metrics.h" | 10 #include "base/metrics/user_metrics.h" |
11 #include "base/strings/sys_string_conversions.h" | 11 #include "base/strings/sys_string_conversions.h" |
12 #include "components/strings/grit/components_strings.h" | 12 #include "components/strings/grit/components_strings.h" |
13 #import "ios/chrome/browser/ui/commands/UIKit+ChromeExecuteCommand.h" | 13 #import "ios/chrome/browser/ui/commands/UIKit+ChromeExecuteCommand.h" |
14 #import "ios/chrome/browser/ui/commands/generic_chrome_command.h" | 14 #import "ios/chrome/browser/ui/commands/generic_chrome_command.h" |
15 #include "ios/chrome/browser/ui/commands/ios_command_ids.h" | 15 #include "ios/chrome/browser/ui/commands/ios_command_ids.h" |
16 #import "ios/chrome/browser/ui/context_menu/context_menu_coordinator.h" | 16 #import "ios/chrome/browser/ui/context_menu/context_menu_coordinator.h" |
17 #import "ios/chrome/browser/ui/ntp/google_landing_data_source.h" | 17 #import "ios/chrome/browser/ui/ntp/google_landing_data_source.h" |
18 #import "ios/chrome/browser/ui/ntp/most_visited_cell.h" | 18 #import "ios/chrome/browser/ui/ntp/most_visited_cell.h" |
19 #import "ios/chrome/browser/ui/ntp/most_visited_layout.h" | 19 #import "ios/chrome/browser/ui/ntp/most_visited_layout.h" |
20 #import "ios/chrome/browser/ui/ntp/new_tab_page_header_constants.h" | 20 #import "ios/chrome/browser/ui/ntp/new_tab_page_header_constants.h" |
21 #import "ios/chrome/browser/ui/ntp/new_tab_page_header_view.h" | 21 #import "ios/chrome/browser/ui/ntp/new_tab_page_header_view.h" |
22 #import "ios/chrome/browser/ui/ntp/whats_new_header_view.h" | 22 #import "ios/chrome/browser/ui/ntp/whats_new_header_view.h" |
23 #import "ios/chrome/browser/ui/overscroll_actions/overscroll_actions_controller.
h" | 23 #import "ios/chrome/browser/ui/overscroll_actions/overscroll_actions_controller.
h" |
| 24 #import "ios/chrome/browser/ui/toolbar/web_toolbar_controller.h" |
24 #include "ios/chrome/browser/ui/ui_util.h" | 25 #include "ios/chrome/browser/ui/ui_util.h" |
25 #import "ios/chrome/browser/ui/uikit_ui_util.h" | 26 #import "ios/chrome/browser/ui/uikit_ui_util.h" |
| 27 #import "ios/chrome/browser/ui/url_loader.h" |
26 #include "ios/chrome/common/string_util.h" | 28 #include "ios/chrome/common/string_util.h" |
27 #include "ios/chrome/grit/ios_strings.h" | 29 #include "ios/chrome/grit/ios_strings.h" |
28 #import "ios/third_party/material_components_ios/src/components/Snackbar/src/Mat
erialSnackbar.h" | 30 #import "ios/third_party/material_components_ios/src/components/Snackbar/src/Mat
erialSnackbar.h" |
29 #import "ios/third_party/material_components_ios/src/components/Typography/src/M
aterialTypography.h" | 31 #import "ios/third_party/material_components_ios/src/components/Typography/src/M
aterialTypography.h" |
30 #import "ios/web/public/web_state/context_menu_params.h" | 32 #import "ios/web/public/web_state/context_menu_params.h" |
31 #import "net/base/mac/url_conversions.h" | 33 #import "net/base/mac/url_conversions.h" |
32 #include "ui/base/l10n/l10n_util.h" | 34 #include "ui/base/l10n/l10n_util.h" |
| 35 #include "ui/base/page_transition_types.h" |
33 | 36 |
34 using base::UserMetricsAction; | 37 using base::UserMetricsAction; |
35 | 38 |
36 namespace { | 39 namespace { |
37 | 40 |
38 enum { | 41 enum { |
39 SectionWithOmnibox, | 42 SectionWithOmnibox, |
40 SectionWithMostVisited, | 43 SectionWithMostVisited, |
41 NumberOfCollectionViewSections, | 44 NumberOfCollectionViewSections, |
42 }; | 45 }; |
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
255 | 258 |
256 @end | 259 @end |
257 | 260 |
258 @implementation GoogleLandingController | 261 @implementation GoogleLandingController |
259 | 262 |
260 @dynamic view; | 263 @dynamic view; |
261 @synthesize logoVendor = _logoVendor; | 264 @synthesize logoVendor = _logoVendor; |
262 @synthesize dataSource = _dataSource; | 265 @synthesize dataSource = _dataSource; |
263 // Property declared in NewTabPagePanelProtocol. | 266 // Property declared in NewTabPagePanelProtocol. |
264 @synthesize delegate = _delegate; | 267 @synthesize delegate = _delegate; |
| 268 @synthesize dispatcher = _dispatcher; |
265 @synthesize isOffTheRecord = _isOffTheRecord; | 269 @synthesize isOffTheRecord = _isOffTheRecord; |
266 @synthesize logoIsShowing = _logoIsShowing; | 270 @synthesize logoIsShowing = _logoIsShowing; |
267 @synthesize promoText = _promoText; | 271 @synthesize promoText = _promoText; |
268 @synthesize promoIcon = _promoIcon; | 272 @synthesize promoIcon = _promoIcon; |
269 @synthesize promoCanShow = _promoCanShow; | 273 @synthesize promoCanShow = _promoCanShow; |
270 @synthesize maximumMostVisitedSitesShown = _maximumMostVisitedSitesShown; | 274 @synthesize maximumMostVisitedSitesShown = _maximumMostVisitedSitesShown; |
271 @synthesize tabCount = _tabCount; | 275 @synthesize tabCount = _tabCount; |
272 @synthesize canGoForward = _canGoForward; | 276 @synthesize canGoForward = _canGoForward; |
273 @synthesize canGoBack = _canGoBack; | 277 @synthesize canGoBack = _canGoBack; |
274 @synthesize voiceSearchIsEnabled = _voiceSearchIsEnabled; | 278 @synthesize voiceSearchIsEnabled = _voiceSearchIsEnabled; |
(...skipping 508 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
783 [[_mostVisitedView collectionViewLayout] invalidateLayout]; | 787 [[_mostVisitedView collectionViewLayout] invalidateLayout]; |
784 } | 788 } |
785 } | 789 } |
786 completion:^(BOOL finished) { | 790 completion:^(BOOL finished) { |
787 // Check to see if we are still scrolled to the top -- it's possible | 791 // Check to see if we are still scrolled to the top -- it's possible |
788 // (and difficult) to resign the first responder and initiate a | 792 // (and difficult) to resign the first responder and initiate a |
789 // -shiftTilesDown before the animation here completes. | 793 // -shiftTilesDown before the animation here completes. |
790 if (_scrolledToTop) { | 794 if (_scrolledToTop) { |
791 _animateHeader = NO; | 795 _animateHeader = NO; |
792 if (!IsIPadIdiom()) { | 796 if (!IsIPadIdiom()) { |
793 [self.dataSource onFakeboxAnimationComplete]; | 797 [self.dispatcher onFakeboxAnimationComplete]; |
794 [_headerView fadeOutShadow]; | 798 [_headerView fadeOutShadow]; |
795 [_searchTapTarget setHidden:YES]; | 799 [_searchTapTarget setHidden:YES]; |
796 } | 800 } |
797 } | 801 } |
798 }]; | 802 }]; |
799 } | 803 } |
800 | 804 |
801 - (void)searchFieldTapped:(id)sender { | 805 - (void)searchFieldTapped:(id)sender { |
802 [self.dataSource focusFakebox]; | 806 [self.dispatcher focusFakebox]; |
803 } | 807 } |
804 | 808 |
805 - (void)blurOmnibox { | 809 - (void)blurOmnibox { |
806 if (_omniboxFocused) { | 810 if (_omniboxFocused) { |
807 [self.dataSource cancelOmniboxEdit]; | 811 [self.dispatcher cancelOmniboxEdit]; |
808 } else { | 812 } else { |
809 [self locationBarResignsFirstResponder]; | 813 [self locationBarResignsFirstResponder]; |
810 } | 814 } |
811 } | 815 } |
812 | 816 |
813 - (void)locationBarResignsFirstResponder { | 817 - (void)locationBarResignsFirstResponder { |
814 if (!_isShowing && !_scrolledToTop) | 818 if (!_isShowing && !_scrolledToTop) |
815 return; | 819 return; |
816 | 820 |
817 _omniboxFocused = NO; | 821 _omniboxFocused = NO; |
818 if ([_contextMenuCoordinator isVisible]) { | 822 if ([_contextMenuCoordinator isVisible]) { |
819 return; | 823 return; |
820 } | 824 } |
821 | 825 |
822 [self shiftTilesDown]; | 826 [self shiftTilesDown]; |
823 } | 827 } |
824 | 828 |
825 - (void)shiftTilesDown { | 829 - (void)shiftTilesDown { |
826 _animateHeader = YES; | 830 _animateHeader = YES; |
827 _scrolledToTop = NO; | 831 _scrolledToTop = NO; |
828 if (!IsIPadIdiom()) { | 832 if (!IsIPadIdiom()) { |
829 [_searchTapTarget setHidden:NO]; | 833 [_searchTapTarget setHidden:NO]; |
830 [self.dataSource onFakeboxBlur]; | 834 [self.dispatcher onFakeboxBlur]; |
831 } | 835 } |
832 | 836 |
833 // Reload most visited sites in case the number of placeholder cells needs to | 837 // Reload most visited sites in case the number of placeholder cells needs to |
834 // be updated after an orientation change. | 838 // be updated after an orientation change. |
835 [_mostVisitedView reloadData]; | 839 [_mostVisitedView reloadData]; |
836 | 840 |
837 // Reshow views that are within range of the most visited collection view | 841 // Reshow views that are within range of the most visited collection view |
838 // (if necessary). | 842 // (if necessary). |
839 [self.view removeGestureRecognizer:_tapGestureRecognizer]; | 843 [self.view removeGestureRecognizer:_tapGestureRecognizer]; |
840 [self.view removeGestureRecognizer:_swipeGestureRecognizer]; | 844 [self.view removeGestureRecognizer:_swipeGestureRecognizer]; |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
969 static_cast<int64_t>(1 * NSEC_PER_SEC)), | 973 static_cast<int64_t>(1 * NSEC_PER_SEC)), |
970 dispatch_get_main_queue(), ^{ | 974 dispatch_get_main_queue(), ^{ |
971 [blockView release]; | 975 [blockView release]; |
972 }); | 976 }); |
973 } | 977 } |
974 | 978 |
975 const NSUInteger visitedIndex = indexPath.row; | 979 const NSUInteger visitedIndex = indexPath.row; |
976 [self blurOmnibox]; | 980 [self blurOmnibox]; |
977 DCHECK(visitedIndex < [self numberOfItems]); | 981 DCHECK(visitedIndex < [self numberOfItems]); |
978 [self.dataSource logMostVisitedClick:visitedIndex tileType:cell.tileType]; | 982 [self.dataSource logMostVisitedClick:visitedIndex tileType:cell.tileType]; |
979 [self.dataSource loadURL:[self urlForIndex:visitedIndex] | 983 [self.dispatcher loadURL:[self urlForIndex:visitedIndex] |
980 referrer:web::Referrer() | 984 referrer:web::Referrer() |
981 transition:ui::PAGE_TRANSITION_AUTO_BOOKMARK | 985 transition:ui::PAGE_TRANSITION_AUTO_BOOKMARK |
982 rendererInitiated:NO]; | 986 rendererInitiated:NO]; |
983 } | 987 } |
984 | 988 |
985 #pragma mark - UICollectionViewDataSource | 989 #pragma mark - UICollectionViewDataSource |
986 | 990 |
987 - (UICollectionReusableView*)collectionView:(UICollectionView*)collectionView | 991 - (UICollectionReusableView*)collectionView:(UICollectionView*)collectionView |
988 viewForSupplementaryElementOfKind:(NSString*)kind | 992 viewForSupplementaryElementOfKind:(NSString*)kind |
989 atIndexPath:(NSIndexPath*)indexPath { | 993 atIndexPath:(NSIndexPath*)indexPath { |
990 DCHECK(kind == UICollectionElementKindSectionHeader); | 994 DCHECK(kind == UICollectionElementKindSectionHeader); |
991 | 995 |
992 if (!_supplementaryViews) | 996 if (!_supplementaryViews) |
993 _supplementaryViews.reset([[NSMutableArray alloc] init]); | 997 _supplementaryViews.reset([[NSMutableArray alloc] init]); |
994 | 998 |
995 if (indexPath.section == SectionWithOmnibox) { | 999 if (indexPath.section == SectionWithOmnibox) { |
996 if (!_headerView) { | 1000 if (!_headerView) { |
997 _headerView.reset([[collectionView | 1001 _headerView.reset([[collectionView |
998 dequeueReusableSupplementaryViewOfKind: | 1002 dequeueReusableSupplementaryViewOfKind: |
999 UICollectionElementKindSectionHeader | 1003 UICollectionElementKindSectionHeader |
1000 withReuseIdentifier:@"header" | 1004 withReuseIdentifier:@"header" |
1001 forIndexPath:indexPath] retain]); | 1005 forIndexPath:indexPath] retain]); |
1002 [_headerView addSubview:[self.logoVendor view]]; | 1006 [_headerView addSubview:[self.logoVendor view]]; |
1003 [_headerView addSubview:_searchTapTarget]; | 1007 [_headerView addSubview:_searchTapTarget]; |
1004 [_headerView addViewsToSearchField:_searchTapTarget]; | 1008 [_headerView addViewsToSearchField:_searchTapTarget]; |
1005 | 1009 |
1006 if (!IsIPadIdiom()) { | 1010 if (!IsIPadIdiom()) { |
1007 // iPhone header also contains a toolbar since the normal toolbar is | 1011 // iPhone header also contains a toolbar since the normal toolbar is |
1008 // hidden. | 1012 // hidden. |
1009 [_headerView addToolbarWithDataSource:self.dataSource]; | 1013 [_headerView addToolbarWithDataSource:self.dataSource |
| 1014 dispatcher:self.dispatcher]; |
1010 [_headerView setToolbarTabCount:self.tabCount]; | 1015 [_headerView setToolbarTabCount:self.tabCount]; |
1011 [_headerView setCanGoForward:self.canGoForward]; | 1016 [_headerView setCanGoForward:self.canGoForward]; |
1012 [_headerView setCanGoBack:self.canGoBack]; | 1017 [_headerView setCanGoBack:self.canGoBack]; |
1013 } | 1018 } |
1014 [_supplementaryViews addObject:_headerView]; | 1019 [_supplementaryViews addObject:_headerView]; |
1015 } | 1020 } |
1016 return _headerView; | 1021 return _headerView; |
1017 } | 1022 } |
1018 | 1023 |
1019 if (indexPath.section == SectionWithMostVisited) { | 1024 if (indexPath.section == SectionWithMostVisited) { |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1132 GURL url = [self urlForIndex:index]; | 1137 GURL url = [self urlForIndex:index]; |
1133 base::WeakNSObject<GoogleLandingController> weakSelf(self); | 1138 base::WeakNSObject<GoogleLandingController> weakSelf(self); |
1134 action = ^{ | 1139 action = ^{ |
1135 base::scoped_nsobject<GoogleLandingController> strongSelf( | 1140 base::scoped_nsobject<GoogleLandingController> strongSelf( |
1136 [weakSelf retain]); | 1141 [weakSelf retain]); |
1137 if (!strongSelf) | 1142 if (!strongSelf) |
1138 return; | 1143 return; |
1139 MostVisitedCell* cell = (MostVisitedCell*)sender.view; | 1144 MostVisitedCell* cell = (MostVisitedCell*)sender.view; |
1140 [[strongSelf dataSource] logMostVisitedClick:index | 1145 [[strongSelf dataSource] logMostVisitedClick:index |
1141 tileType:cell.tileType]; | 1146 tileType:cell.tileType]; |
1142 [[strongSelf dataSource] webPageOrderedOpen:url | 1147 [[strongSelf dispatcher] webPageOrderedOpen:url |
1143 referrer:web::Referrer() | 1148 referrer:web::Referrer() |
1144 inBackground:YES | 1149 inBackground:YES |
1145 appendTo:kCurrentTab]; | 1150 appendTo:kCurrentTab]; |
1146 }; | 1151 }; |
1147 [_contextMenuCoordinator | 1152 [_contextMenuCoordinator |
1148 addItemWithTitle:l10n_util::GetNSStringWithFixup( | 1153 addItemWithTitle:l10n_util::GetNSStringWithFixup( |
1149 IDS_IOS_CONTENT_CONTEXT_OPENLINKNEWTAB) | 1154 IDS_IOS_CONTENT_CONTEXT_OPENLINKNEWTAB) |
1150 action:action]; | 1155 action:action]; |
1151 | 1156 |
1152 if (!self.isOffTheRecord) { | 1157 if (!self.isOffTheRecord) { |
1153 // Open in Incognito Tab. | 1158 // Open in Incognito Tab. |
1154 action = ^{ | 1159 action = ^{ |
1155 base::scoped_nsobject<GoogleLandingController> strongSelf( | 1160 base::scoped_nsobject<GoogleLandingController> strongSelf( |
1156 [weakSelf retain]); | 1161 [weakSelf retain]); |
1157 if (!strongSelf) | 1162 if (!strongSelf) |
1158 return; | 1163 return; |
1159 MostVisitedCell* cell = (MostVisitedCell*)sender.view; | 1164 MostVisitedCell* cell = (MostVisitedCell*)sender.view; |
1160 [[strongSelf dataSource] logMostVisitedClick:index | 1165 [[strongSelf dataSource] logMostVisitedClick:index |
1161 tileType:cell.tileType]; | 1166 tileType:cell.tileType]; |
1162 [[strongSelf dataSource] webPageOrderedOpen:url | 1167 [[strongSelf dispatcher] webPageOrderedOpen:url |
1163 referrer:web::Referrer() | 1168 referrer:web::Referrer() |
1164 inIncognito:YES | 1169 inIncognito:YES |
1165 inBackground:NO | 1170 inBackground:NO |
1166 appendTo:kCurrentTab]; | 1171 appendTo:kCurrentTab]; |
1167 }; | 1172 }; |
1168 [_contextMenuCoordinator | 1173 [_contextMenuCoordinator |
1169 addItemWithTitle:l10n_util::GetNSStringWithFixup( | 1174 addItemWithTitle:l10n_util::GetNSStringWithFixup( |
1170 IDS_IOS_CONTENT_CONTEXT_OPENLINKNEWINCOGNITOTAB) | 1175 IDS_IOS_CONTENT_CONTEXT_OPENLINKNEWINCOGNITOTAB) |
1171 action:action]; | 1176 action:action]; |
1172 } | 1177 } |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1213 TriggerHapticFeedbackForNotification(UINotificationFeedbackTypeSuccess); | 1218 TriggerHapticFeedbackForNotification(UINotificationFeedbackTypeSuccess); |
1214 MDCSnackbarMessage* message = [MDCSnackbarMessage | 1219 MDCSnackbarMessage* message = [MDCSnackbarMessage |
1215 messageWithText:l10n_util::GetNSString( | 1220 messageWithText:l10n_util::GetNSString( |
1216 IDS_IOS_NEW_TAB_MOST_VISITED_ITEM_REMOVED)]; | 1221 IDS_IOS_NEW_TAB_MOST_VISITED_ITEM_REMOVED)]; |
1217 message.action = action; | 1222 message.action = action; |
1218 message.category = @"MostVisitedUndo"; | 1223 message.category = @"MostVisitedUndo"; |
1219 [MDCSnackbarManager showMessage:message]; | 1224 [MDCSnackbarManager showMessage:message]; |
1220 } | 1225 } |
1221 | 1226 |
1222 - (void)onPromoLabelTapped { | 1227 - (void)onPromoLabelTapped { |
1223 [self.dataSource cancelOmniboxEdit]; | 1228 [self.dispatcher cancelOmniboxEdit]; |
1224 [_promoHeaderView setHidden:YES]; | 1229 [_promoHeaderView setHidden:YES]; |
1225 [self.view setNeedsLayout]; | 1230 [self.view setNeedsLayout]; |
1226 [self.dataSource promoTapped]; | 1231 [self.dataSource promoTapped]; |
1227 } | 1232 } |
1228 | 1233 |
1229 // Returns the Y value to use for the scroll view's contentOffset when scrolling | 1234 // Returns the Y value to use for the scroll view's contentOffset when scrolling |
1230 // the omnibox to the top of the screen. | 1235 // the omnibox to the top of the screen. |
1231 - (CGFloat)pinnedOffsetY { | 1236 - (CGFloat)pinnedOffsetY { |
1232 CGFloat headerHeight = [_headerView frame].size.height; | 1237 CGFloat headerHeight = [_headerView frame].size.height; |
1233 CGFloat offsetY = | 1238 CGFloat offsetY = |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1310 #pragma mark - UIScrollViewDelegate Methods. | 1315 #pragma mark - UIScrollViewDelegate Methods. |
1311 | 1316 |
1312 - (void)scrollViewDidScroll:(UIScrollView*)scrollView { | 1317 - (void)scrollViewDidScroll:(UIScrollView*)scrollView { |
1313 [self.delegate updateNtpBarShadowForPanelController:self]; | 1318 [self.delegate updateNtpBarShadowForPanelController:self]; |
1314 [_overscrollActionsController scrollViewDidScroll:scrollView]; | 1319 [_overscrollActionsController scrollViewDidScroll:scrollView]; |
1315 | 1320 |
1316 // Blur the omnibox when the scroll view is scrolled below the pinned offset. | 1321 // Blur the omnibox when the scroll view is scrolled below the pinned offset. |
1317 CGFloat pinnedOffsetY = [self pinnedOffsetY]; | 1322 CGFloat pinnedOffsetY = [self pinnedOffsetY]; |
1318 if (_omniboxFocused && scrollView.dragging && | 1323 if (_omniboxFocused && scrollView.dragging && |
1319 scrollView.contentOffset.y < pinnedOffsetY) { | 1324 scrollView.contentOffset.y < pinnedOffsetY) { |
1320 [self.dataSource cancelOmniboxEdit]; | 1325 [self.dispatcher cancelOmniboxEdit]; |
1321 } | 1326 } |
1322 | 1327 |
1323 if (IsIPadIdiom()) { | 1328 if (IsIPadIdiom()) { |
1324 return; | 1329 return; |
1325 } | 1330 } |
1326 | 1331 |
1327 if (_animateHeader) { | 1332 if (_animateHeader) { |
1328 [self updateSearchField]; | 1333 [self updateSearchField]; |
1329 } | 1334 } |
1330 } | 1335 } |
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1507 - (void)setCanGoForward:(BOOL)canGoForward { | 1512 - (void)setCanGoForward:(BOOL)canGoForward { |
1508 _canGoForward = canGoForward; | 1513 _canGoForward = canGoForward; |
1509 [_headerView setCanGoForward:self.canGoForward]; | 1514 [_headerView setCanGoForward:self.canGoForward]; |
1510 } | 1515 } |
1511 | 1516 |
1512 - (void)setCanGoBack:(BOOL)canGoBack { | 1517 - (void)setCanGoBack:(BOOL)canGoBack { |
1513 _canGoBack = canGoBack; | 1518 _canGoBack = canGoBack; |
1514 [_headerView setCanGoBack:self.canGoBack]; | 1519 [_headerView setCanGoBack:self.canGoBack]; |
1515 } | 1520 } |
1516 @end | 1521 @end |
OLD | NEW |