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

Unified Diff: ios/chrome/browser/payments/payment_request_picker_view_controller.mm

Issue 2778343002: [Payment Request] Picker view + showcase integration + egtests (Closed)
Patch Set: Addressed comments Created 3 years, 8 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 side-by-side diff with in-line comments
Download patch
Index: ios/chrome/browser/payments/payment_request_picker_view_controller.mm
diff --git a/ios/chrome/browser/payments/payment_request_picker_view_controller.mm b/ios/chrome/browser/payments/payment_request_picker_view_controller.mm
new file mode 100644
index 0000000000000000000000000000000000000000..77977025349f39b4c428c908d983c7a6afc798a7
--- /dev/null
+++ b/ios/chrome/browser/payments/payment_request_picker_view_controller.mm
@@ -0,0 +1,251 @@
+// Copyright 2017 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/chrome/browser/payments/payment_request_picker_view_controller.h"
+
+#import "base/logging.h"
+#import "base/mac/foundation_util.h"
+#import "ios/chrome/browser/payments/payment_request_picker_row.h"
+
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
+NSString* const kPaymentRequestPickerRowAccessibilityID =
+ @"kPaymentRequestPickerRowAccessibilityID";
+NSString* const kPaymentRequestPickerSearchBarAccessibilityID =
+ @"kPaymentRequestPickerSearchBarAccessibilityID";
+
+namespace {
+NSString* const kPaymentRequestPickerViewControllerAccessibilityID =
+ @"kPaymentRequestPickerViewControllerAccessibilityID";
+} // namespace
+
+@interface PaymentRequestPickerViewController ()<UISearchResultsUpdating>
+
+// Search controller that contains search bar.
+@property(nonatomic, strong) UISearchController* searchController;
+
+// Full data set displayed when tableView is not filtered.
+@property(nonatomic, strong) NSArray<PickerRow*>* allRows;
+
+// Displayed rows in the tableView.
+@property(nonatomic, strong) NSArray<PickerRow*>* displayedRows;
+
+// Selected row.
+@property(nonatomic, strong) PickerRow* selectedRow;
+
+@property(nonatomic, strong)
+ NSDictionary<NSString*, NSArray<PickerRow*>*>* sectionTitleToSectionRowsMap;
+
+@end
+
+@implementation PaymentRequestPickerViewController
+@synthesize searchController = _searchController;
+@synthesize allRows = _allRows;
+@synthesize displayedRows = _displayedRows;
+@synthesize selectedRow = _selectedRow;
+@synthesize sectionTitleToSectionRowsMap = _sectionTitleToSectionRowsMap;
+@synthesize delegate = _delegate;
+
+- (instancetype)initWithRows:(NSArray<PickerRow*>*)rows
+ selected:(PickerRow*)selectedRow {
+ self = [super initWithStyle:UITableViewStylePlain];
+ if (self) {
+ self.allRows = [rows sortedArrayUsingComparator:^NSComparisonResult(
+ PickerRow* row1, PickerRow* row2) {
+ return [row1.label localizedCaseInsensitiveCompare:row2.label];
+ }];
+ self.selectedRow = selectedRow;
+ // Default to displaying all the rows.
+ self.displayedRows = self.allRows;
+ }
+ return self;
+}
+
+- (void)setDisplayedRows:(NSArray<PickerRow*>*)displayedRows {
+ _displayedRows = displayedRows;
+
+ // Update the mapping from section titles to rows in that section, for
+ // currently displayed rows.
+ [self updateSectionTitleToSectionRowsMap];
+}
+
+#pragma mark - UIViewController
+
+- (void)viewDidLoad {
+ [super viewDidLoad];
+
+ self.tableView.rowHeight = 48.0f; // The same as MDCCellDefaultOneLineHeight.
+ self.tableView.accessibilityIdentifier =
+ kPaymentRequestPickerViewControllerAccessibilityID;
+
+ self.searchController =
+ [[UISearchController alloc] initWithSearchResultsController:nil];
+ self.searchController.searchResultsUpdater = self;
+ self.searchController.dimsBackgroundDuringPresentation = NO;
+ self.searchController.searchBar.accessibilityIdentifier =
+ kPaymentRequestPickerSearchBarAccessibilityID;
+ self.tableView.tableHeaderView = self.searchController.searchBar;
+
+ // Presentation of searchController will walk up the view controller hierarchy
+ // until it finds the root view controller or one that defines a presentation
+ // context. Make this class the presentation context so that the search
+ // controller does not present on top of the navigation controller.
+ self.definesPresentationContext = YES;
+}
+
+#pragma mark - UITableViewDataSource
+
+- (NSArray<NSString*>*)sectionIndexTitlesForTableView:(UITableView*)tableView {
+ return [self sectionTitles];
+}
+
+- (NSInteger)numberOfSectionsInTableView:(UITableView*)tableView {
+ return [[self sectionTitles] count];
+}
+
+- (NSString*)tableView:(UITableView*)tableView
+ titleForHeaderInSection:(NSInteger)section {
+ return [[self sectionTitles] objectAtIndex:section];
+}
+
+- (NSInteger)tableView:(UITableView*)tableView
+ numberOfRowsInSection:(NSInteger)section {
+ return [[self rowsInSection:section] count];
+}
+
+- (UITableViewCell*)tableView:(UITableView*)tableView
+ cellForRowAtIndexPath:(NSIndexPath*)indexPath {
+ UITableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:@"cell"];
+ if (!cell) {
+ cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle
+ reuseIdentifier:@"cell"];
+ cell.isAccessibilityElement = YES;
+ cell.accessibilityIdentifier = kPaymentRequestPickerRowAccessibilityID;
+ }
+ PickerRow* row =
+ [[self rowsInSection:indexPath.section] objectAtIndex:indexPath.row];
+ cell.textLabel.text = row.label;
+ cell.accessoryType = (row == self.selectedRow)
+ ? UITableViewCellAccessoryCheckmark
+ : UITableViewCellAccessoryNone;
+ if (row == self.selectedRow)
+ cell.accessibilityTraits |= UIAccessibilityTraitSelected;
+ else
+ cell.accessibilityTraits &= ~UIAccessibilityTraitSelected;
+
+ return cell;
+}
+
+#pragma mark - UITableViewDelegate
+
+- (void)tableView:(UITableView*)tableView
+ didSelectRowAtIndexPath:(NSIndexPath*)indexPath {
+ if (self.selectedRow) {
+ NSIndexPath* oldSelectedIndexPath = [self indexPathForRow:self.selectedRow];
+ self.selectedRow = nil;
+ // Reload the previously selected row if it is displaying.
+ if (oldSelectedIndexPath) {
+ [self.tableView reloadRowsAtIndexPaths:@[ oldSelectedIndexPath ]
+ withRowAnimation:UITableViewRowAnimationFade];
+ }
+ }
+
+ self.selectedRow =
+ [[self rowsInSection:indexPath.section] objectAtIndex:indexPath.row];
+ // Reload the newly selected row.
+ [self.tableView reloadRowsAtIndexPaths:@[ indexPath ]
+ withRowAnimation:UITableViewRowAnimationFade];
+
+ [_delegate paymentRequestPickerViewController:self
+ didSelectRow:self.selectedRow];
+}
+
+#pragma mark - UISearchResultsUpdating
+
+- (void)updateSearchResultsForSearchController:
+ (UISearchController*)searchController {
+ NSString* searchText = searchController.searchBar.text;
+
+ // Filter |allRows| for |searchText| and reload the tableView. If |searchText|
+ // is empty, tableView will be loaded with |allRows|.
+ if (searchText.length != 0) {
+ // The search is case-insensitive and ignores diacritics.
+ NSPredicate* predicate =
+ [NSPredicate predicateWithFormat:@"label CONTAINS[cd] %@", searchText];
+ self.displayedRows = [self.allRows filteredArrayUsingPredicate:predicate];
+ } else {
+ self.displayedRows = self.allRows;
+ }
+
+ [self.tableView reloadData];
+}
+
+#pragma mark - Private
+
+// Creates a mapping from section titles to rows in that section, for currently
+// displaying rows, and updates |sectionTitleToSectionRowsMap|.
+- (void)updateSectionTitleToSectionRowsMap {
+ NSMutableDictionary<NSString*, NSArray<PickerRow*>*>*
+ sectionTitleToSectionRowsMap = [[NSMutableDictionary alloc] init];
+
+ for (PickerRow* row in self.displayedRows) {
+ NSString* sectionTitle = [self sectionTitleForRow:row];
+ NSMutableArray<PickerRow*>* sectionRows =
+ base::mac::ObjCCastStrict<NSMutableArray<PickerRow*>>(
+ sectionTitleToSectionRowsMap[sectionTitle]);
+ if (!sectionRows)
+ sectionRows = [[NSMutableArray alloc] init];
+ [sectionRows addObject:row];
+ [sectionTitleToSectionRowsMap setObject:sectionRows forKey:sectionTitle];
+ }
+
+ self.sectionTitleToSectionRowsMap = sectionTitleToSectionRowsMap;
+}
+
+// Returns the indexPath for |row| by calculating its section and its index
+// within the section. Returns nil if the row is not currently displaying.
+- (NSIndexPath*)indexPathForRow:(PickerRow*)row {
+ NSString* sectionTitle = [self sectionTitleForRow:row];
+
+ NSInteger section = [[self sectionTitles] indexOfObject:sectionTitle];
+ if (section == NSNotFound)
+ return nil;
+
+ NSInteger indexInSection =
+ [self.sectionTitleToSectionRowsMap[sectionTitle] indexOfObject:row];
+ if (indexInSection == NSNotFound)
+ return nil;
+
+ return [NSIndexPath indexPathForRow:indexInSection inSection:section];
+}
+
+// Returns the titles for the displayed sections in the tableView.
+- (NSArray<NSString*>*)sectionTitles {
+ return [[self.sectionTitleToSectionRowsMap allKeys]
+ sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)];
+}
+
+// Returns the displayed rows in the given section.
+- (NSArray<PickerRow*>*)rowsInSection:(NSInteger)section {
+ NSArray<NSString*>* sectionTitles = [self sectionTitles];
+ DCHECK(section >= 0 && section < static_cast<NSInteger>(sectionTitles.count));
+
+ NSString* sectionTitle = [sectionTitles objectAtIndex:section];
+
+ return self.sectionTitleToSectionRowsMap[sectionTitle];
+}
+
+// Returns the title for the section the given row gets added to. The section
+// title for a row is the capitalized first letter of the label for that row.
+- (NSString*)sectionTitleForRow:(PickerRow*)row {
+ return [[row.label substringToIndex:1] uppercaseString];
+}
+
+- (NSString*)description {
+ return kPaymentRequestPickerViewControllerAccessibilityID;
+}
+
+@end
« no previous file with comments | « ios/chrome/browser/payments/payment_request_picker_view_controller.h ('k') | ios/showcase/common/protocol_alerter.mm » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698