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

Unified Diff: ios/chrome/browser/ui/toolbar/web_toolbar_controller.mm

Issue 2914193002: [iOS] Factor out the KeyboardAccessoryView. (Closed)
Patch Set: 2 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 side-by-side diff with in-line comments
Download patch
Index: ios/chrome/browser/ui/toolbar/web_toolbar_controller.mm
diff --git a/ios/chrome/browser/ui/toolbar/web_toolbar_controller.mm b/ios/chrome/browser/ui/toolbar/web_toolbar_controller.mm
index 13205e9cb8200f1fe13af1d06f0e2a9b77b70405..ba6ae8de275f17080ee428288b0bbbeba5c91462 100644
--- a/ios/chrome/browser/ui/toolbar/web_toolbar_controller.mm
+++ b/ios/chrome/browser/ui/toolbar/web_toolbar_controller.mm
@@ -46,6 +46,7 @@
#import "ios/chrome/browser/ui/popup_menu/popup_menu_view.h"
#import "ios/chrome/browser/ui/reversed_animation.h"
#include "ios/chrome/browser/ui/rtl_geometry.h"
+#import "ios/chrome/browser/ui/toolbar/keyboard_accessory_view.h"
#import "ios/chrome/browser/ui/toolbar/toolbar_controller+protected.h"
#import "ios/chrome/browser/ui/toolbar/toolbar_controller.h"
#import "ios/chrome/browser/ui/toolbar/toolbar_model_ios.h"
@@ -115,8 +116,6 @@
const CGFloat kCancelButtonTopMargin = 4.0;
const CGFloat kCancelButtonLeadingMargin = 7.0;
const CGFloat kCancelButtonWidth = 40.0;
-const CGFloat kIpadButtonTitleFontSize = 20.0;
-const CGFloat kIphoneButtonTitleFontSize = 15.0;
// Additional offset to adjust the y coordinate of the determinate progress bar
// up by.
@@ -222,23 +221,11 @@ CGRect RectShiftedDownAndResizedForStatusBar(CGRect rect) {
} // namespace
-// View for the accessory view above the keyboard. Subclassed to allow playing
-// input clicks when pressed.
-@interface KeyboardAccessoryView : UIInputView<UIInputViewAudioFeedback>
-@end
-
-@implementation KeyboardAccessoryView
-
-- (BOOL)enableInputClicksWhenVisible {
- return YES;
-}
-
-@end
-
// TODO(crbug.com/619982) Remove this block and add CAAnimationDelegate when we
// switch the main bots to Xcode 8.
#if defined(__IPHONE_10_0) && (__IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0)
-@interface WebToolbarController ()<CAAnimationDelegate>
+@interface WebToolbarController ()<CAAnimationDelegate,
+ KeyboardAccessoryViewDelegate>
@end
#endif
@@ -255,8 +242,7 @@ @interface WebToolbarController ()<LocationBarDelegate,
UIButton* _voiceSearchButton;
OmniboxTextFieldIOS* _omniBox;
UIButton* _cancelButton;
- UIView* _keyBoardAccessoryView;
- UIButton* _keyboardVoiceSearchButton;
+ KeyboardAccessoryView* _keyBoardAccessoryView;
// Progress bar used to show what fraction of the page has loaded.
MDCProgressView* _determinateProgressView;
UIImageView* _omniboxBackground;
@@ -344,7 +330,6 @@ - (void)moveVoiceOverToVoiceSearchButton;
- (void)updateToolbarAlphaForFrame:(CGRect)frame;
// Navigate to |query| from omnibox.
- (void)loadURLForQuery:(NSString*)query;
-- (UIView*)keyboardButtonWithTitle:(NSString*)title frame:(CGRect)frame;
// Lazily instantiate the keyboard accessory view.
- (UIView*)keyboardAccessoryView;
- (void)preloadVoiceSearch:(id)sender;
@@ -368,8 +353,6 @@ - (void)animationDidStop:(CAAnimation*)anim finished:(BOOL)flag;
- (void)updateSnapshotWithWidth:(CGFloat)width forced:(BOOL)force;
// Insert 'com' without the period if cursor is directly after a period.
- (NSString*)updateTextForDotCom:(NSString*)text;
-// Handle the user pressing a key in the keyboard accessory view.
-- (void)pressKey:(id)sender;
@end
@implementation WebToolbarController
@@ -892,10 +875,10 @@ - (void)traitCollectionDidChange:(UITraitCollection*)previousTraitCollection {
[self updateToolbarState];
// Update keyboard accessory views.
- BOOL hidden = [_keyboardVoiceSearchButton isHidden];
+ auto mode = _keyBoardAccessoryView.mode;
_keyBoardAccessoryView = nil;
[_omniBox setInputAccessoryView:[self keyboardAccessoryView]];
- [_keyboardVoiceSearchButton setHidden:hidden];
+ _keyBoardAccessoryView.mode = mode;
if ([_omniBox isFirstResponder]) {
[_omniBox reloadInputViews];
}
@@ -968,8 +951,6 @@ - (IBAction)recordUserMetrics:(id)sender {
base::RecordAction(UserMetricsAction("MobileToolbarStop"));
} else if (sender == _voiceSearchButton) {
base::RecordAction(UserMetricsAction("MobileToolbarVoiceSearch"));
- } else if (sender == _keyboardVoiceSearchButton) {
- base::RecordAction(UserMetricsAction("MobileCustomRowVoiceSearch"));
} else if (sender == _starButton) {
base::RecordAction(UserMetricsAction("MobileToolbarToggleBookmark"));
} else {
@@ -1280,7 +1261,7 @@ - (void)locationBarHasBecomeFirstResponder {
[self.delegate locationBarDidBecomeFirstResponder:self];
[self animateMaterialOmnibox];
- [_keyboardVoiceSearchButton setHidden:NO];
+ _keyBoardAccessoryView.mode = VOICE_SEARCH;
// Record the appropriate user action for focusing the omnibox.
web::WebState* webState = [self.delegate currentWebState];
@@ -1318,10 +1299,14 @@ - (void)locationBarChanged {
// If the voice search button is visible but about to be hidden (i.e.
// the omnibox is no longer empty) then this is the first omnibox text so
// record a user action.
- if (![_keyboardVoiceSearchButton isHidden] && editingAndNotEmpty) {
+ if (_keyBoardAccessoryView.mode == VOICE_SEARCH && editingAndNotEmpty) {
base::RecordAction(UserMetricsAction("MobileFirstTextInOmnibox"));
}
- [_keyboardVoiceSearchButton setHidden:editingAndNotEmpty];
+ if (editingAndNotEmpty) {
+ _keyBoardAccessoryView.mode = KEY_SHORTCUTS;
+ } else {
+ _keyBoardAccessoryView.mode = VOICE_SEARCH;
+ }
}
- (web::WebState*)getWebState {
@@ -1473,6 +1458,35 @@ - (void)receiveQRScannerResult:(NSString*)result loadImmediately:(BOOL)load {
}
#pragma mark -
+#pragma mark KeyboardAccessoryViewDelegate
+
+- (void)keyboardAccessoryVoiceSearchTouchDown {
+ if (ios::GetChromeBrowserProvider()
+ ->GetVoiceSearchProvider()
+ ->IsVoiceSearchEnabled()) {
+ [self preloadVoiceSearch:_keyBoardAccessoryView];
+ }
+}
+
+- (void)keyboardAccessoryVoiceSearchTouchUpInside {
+ if (ios::GetChromeBrowserProvider()
+ ->GetVoiceSearchProvider()
+ ->IsVoiceSearchEnabled()) {
+ base::RecordAction(UserMetricsAction("MobileCustomRowVoiceSearch"));
+ GenericChromeCommand* command =
+ [[GenericChromeCommand alloc] initWithTag:IDC_VOICE_SEARCH];
+ [_keyBoardAccessoryView chromeExecuteCommand:command];
+ } else {
+ _keyBoardAccessoryView.mode = KEY_SHORTCUTS;
+ }
+}
+
+- (void)keyPressed:(NSString*)title {
+ NSString* text = [self updateTextForDotCom:title];
+ [_omniBox insertTextWhileEditing:text];
+}
+
+#pragma mark -
#pragma mark Private methods.
- (UIButton*)cancelButton {
@@ -1827,136 +1841,18 @@ - (void)loadURLForQuery:(NSString*)query {
}
}
-- (UIView*)keyboardButtonWithTitle:(NSString*)title frame:(CGRect)frame {
- UIButton* button = [UIButton buttonWithType:UIButtonTypeCustom];
- UIFont* font = nil;
- UIImage* backgroundImage = nil;
- if (IsIPadIdiom()) {
- font = GetUIFont(FONT_HELVETICA, false, kIpadButtonTitleFontSize);
- } else {
- font = GetUIFont(FONT_HELVETICA, true, kIphoneButtonTitleFontSize);
- }
- // TODO(leng): Consider moving these images to pak files as well.
- backgroundImage = [UIImage imageNamed:@"keyboard_button"];
-
- button.frame = frame;
- [button setTitle:title forState:UIControlStateNormal];
- [button setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
- [button.titleLabel setFont:font];
- [button setBackgroundImage:backgroundImage forState:UIControlStateNormal];
- [button addTarget:self
- action:@selector(pressKey:)
- forControlEvents:UIControlEventTouchUpInside];
- button.isAccessibilityElement = YES;
- [button setAccessibilityLabel:title];
-
- return button;
-}
-
- (UIView*)keyboardAccessoryView {
- const CGFloat kViewHeightTablet = 70.0;
- const CGFloat kViewHeightPhone = 43.0;
- const CGFloat kButtonInset = 5.0;
- const CGFloat kButtonSizeXTablet = 61.0;
- const CGFloat kButtonSizeXPhone = 46.0;
- const CGFloat kButtonSizeYTablet = 62.0;
- const CGFloat kButtonSizeYPhone = 35.0;
- const CGFloat kBetweenButtonSpacing = 15.0;
- const CGFloat kBetweenButtonSpacingPhone = 7.0;
-
- if (_keyBoardAccessoryView)
- return _keyBoardAccessoryView;
-
- const BOOL isTablet = IsIPadIdiom() && !IsCompactTablet(self.view);
-
- // TODO(pinkerton): purge this view when low memory.
- CGFloat width = [[UIScreen mainScreen] bounds].size.width;
- CGFloat height = isTablet ? kViewHeightTablet : kViewHeightPhone;
- CGRect frame = CGRectMake(0.0, 0.0, width, height);
-
- _keyBoardAccessoryView =
- [[KeyboardAccessoryView alloc] initWithFrame:frame
- inputViewStyle:UIInputViewStyleKeyboard];
- [_keyBoardAccessoryView setAutoresizingMask:UIViewAutoresizingFlexibleWidth];
-
- NSArray* buttonTitles =
- [NSArray arrayWithObjects:@":", @".", @"-", @"/", kDotComTLD, nil];
-
- // Center buttons in available space by placing them within a parent view
- // that auto-centers.
- CGFloat betweenButtonSpacing =
- isTablet ? kBetweenButtonSpacing : kBetweenButtonSpacingPhone;
- const CGFloat buttonWidth = isTablet ? kButtonSizeXTablet : kButtonSizeXPhone;
-
- CGFloat totalWidth = (buttonTitles.count * buttonWidth) +
- ((buttonTitles.count - 1) * betweenButtonSpacing);
- CGFloat indent = floor((width - totalWidth) / 2.0);
- if (indent < kButtonInset)
- indent = kButtonInset;
- CGRect parentViewRect = CGRectMake(indent, 0.0, totalWidth, height);
- UIView* parentView = [[UIView alloc] initWithFrame:parentViewRect];
- [parentView setAutoresizingMask:UIViewAutoresizingFlexibleLeftMargin |
- UIViewAutoresizingFlexibleRightMargin];
- [_keyBoardAccessoryView addSubview:parentView];
-
- // Create the buttons, starting at the left edge of |parentView|.
- CGRect currentFrame =
- CGRectMake(0.0, kButtonInset, buttonWidth,
- isTablet ? kButtonSizeYTablet : kButtonSizeYPhone);
-
- for (NSString* title in buttonTitles) {
- UIView* button = [self keyboardButtonWithTitle:title frame:currentFrame];
- [parentView addSubview:button];
- currentFrame.origin.x = CGRectGetMaxX(currentFrame) + betweenButtonSpacing;
- }
-
- // Create the voice search button and add it to _keyBoardAccessoryView over
- // the text buttons.
- _keyboardVoiceSearchButton = [UIButton buttonWithType:UIButtonTypeCustom];
- [_keyboardVoiceSearchButton
- setAutoresizingMask:UIViewAutoresizingFlexibleWidth];
- [_keyboardVoiceSearchButton setTag:IDC_VOICE_SEARCH];
- SetA11yLabelAndUiAutomationName(_keyboardVoiceSearchButton,
- IDS_IOS_ACCNAME_VOICE_SEARCH,
- @"Voice Search");
- // TODO(leng): Consider moving these icons into a pak file.
- UIImage* voiceRow = [UIImage imageNamed:@"custom_row_voice"];
- UIImage* voiceRowPressed = [UIImage imageNamed:@"custom_row_voice_pressed"];
- [_keyboardVoiceSearchButton setBackgroundImage:voiceRow
- forState:UIControlStateNormal];
- [_keyboardVoiceSearchButton setBackgroundImage:voiceRowPressed
- forState:UIControlStateHighlighted];
-
- UIImage* voiceIcon = [UIImage imageNamed:@"voice_icon_keyboard_accessory"];
- [_keyboardVoiceSearchButton setAdjustsImageWhenHighlighted:NO];
- [_keyboardVoiceSearchButton setImage:voiceIcon forState:UIControlStateNormal];
- [_keyboardVoiceSearchButton setFrame:[_keyBoardAccessoryView bounds]];
-
- // Only add the voice search actions if voice search is enabled.
- if (ios::GetChromeBrowserProvider()
- ->GetVoiceSearchProvider()
- ->IsVoiceSearchEnabled()) {
- [_keyboardVoiceSearchButton addTarget:self
- action:@selector(recordUserMetrics:)
- forControlEvents:UIControlEventTouchUpInside];
- [_keyboardVoiceSearchButton addTarget:_keyboardVoiceSearchButton
- action:@selector(chromeExecuteCommand:)
- forControlEvents:UIControlEventTouchUpInside];
- [_keyboardVoiceSearchButton addTarget:self
- action:@selector(preloadVoiceSearch:)
- forControlEvents:UIControlEventTouchDown];
- } else {
- [_keyboardVoiceSearchButton addTarget:self
- action:@selector(ignoreVoiceSearch:)
- forControlEvents:UIControlEventTouchUpInside];
+ if (!_keyBoardAccessoryView) {
+ NSArray<NSString*>* buttonTitles =
+ [NSArray arrayWithObjects:@":", @".", @"-", @"/", kDotComTLD, nil];
+ _keyBoardAccessoryView =
+ [[KeyboardAccessoryView alloc] initWithButtons:buttonTitles
+ delegate:self];
+ [_keyBoardAccessoryView
+ setAutoresizingMask:UIViewAutoresizingFlexibleWidth];
+ _hardwareKeyboardWatcher = [[HardwareKeyboardWatcher alloc]
+ initWithAccessoryView:_keyBoardAccessoryView];
}
-
- [_keyBoardAccessoryView addSubview:_keyboardVoiceSearchButton];
-
- // Reset the external keyboard watcher.
- _hardwareKeyboardWatcher = [[HardwareKeyboardWatcher alloc]
- initWithAccessoryView:_keyBoardAccessoryView];
-
return _keyBoardAccessoryView;
}
@@ -1964,10 +1860,6 @@ - (void)preloadVoiceSearch:(id)sender {
DCHECK(ios::GetChromeBrowserProvider()
->GetVoiceSearchProvider()
->IsVoiceSearchEnabled());
- [sender removeTarget:self
- action:@selector(preloadVoiceSearch:)
- forControlEvents:UIControlEventTouchDown];
-
// Use a GenericChromeCommand because |sender| already has a tag set for a
// different command.
GenericChromeCommand* command =
@@ -1975,12 +1867,6 @@ - (void)preloadVoiceSearch:(id)sender {
[sender chromeExecuteCommand:command];
}
-// Called when the keyboard voice search button is tapped with voice search
-// disabled. Hides the voice search button but takes no other action.
-- (void)ignoreVoiceSearch:(id)sender {
- [_keyboardVoiceSearchButton setHidden:YES];
-}
-
- (CGFloat)omniboxLeading {
// Compute what the leading (x-origin) position for the omniboox should be
// based on what other controls are active.
@@ -2530,13 +2416,6 @@ - (NSString*)updateTextForDotCom:(NSString*)text {
return text;
}
-- (void)pressKey:(id)sender {
- DCHECK([sender isKindOfClass:[UIButton class]]);
- [[UIDevice currentDevice] playInputClick];
- NSString* text = [self updateTextForDotCom:[sender currentTitle]];
- [_omniBox insertTextWhileEditing:text];
-}
-
@end
@implementation WebToolbarController (Testing)

Powered by Google App Engine
This is Rietveld 408576698