forked from chromium/chromium
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Creates coordinator for displaying alerts
This CL creates an AlertControllerCoordinator which can handle displaying alerts. This coordinator can display action sheets and modal alerts. BUG=629515 Review-Url: https://codereview.chromium.org/2119373002 Cr-Commit-Position: refs/heads/master@{#407431}
- Loading branch information
gambard
authored and
Commit bot
committed
Jul 25, 2016
1 parent
b9e3d96
commit b61a961
Showing
8 changed files
with
518 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
gambard@chromium.org | ||
jyquinn@chromium.org |
53 changes: 53 additions & 0 deletions
53
ios/chrome/browser/ui/alert_coordinator/alert_coordinator.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
// Copyright 2016 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. | ||
|
||
#ifndef IOS_CHROME_BROWSER_UI_ALERT_COORDINATOR_ALERT_COORDINATOR_H_ | ||
#define IOS_CHROME_BROWSER_UI_ALERT_COORDINATOR_ALERT_COORDINATOR_H_ | ||
|
||
#import <UIKit/UIKit.h> | ||
|
||
#include "base/ios/block_types.h" | ||
#import "ios/chrome/browser/chrome_coordinator.h" | ||
|
||
// A coordinator specialization for the case where the coordinator is | ||
// creating and managing an alert (popup or action sheet) to be displayed to the | ||
// user. Dismiss it with no animation. | ||
// The type of alert displayed depends on the init called. | ||
// Calling |-stop| on this coordinator destroys the current alert. | ||
@interface AlertCoordinator : ChromeCoordinator | ||
|
||
// Whether a cancel button has been added. | ||
@property(nonatomic, readonly) BOOL cancelButtonAdded; | ||
// Message of the alert. | ||
@property(nonatomic, copy) NSString* message; | ||
// Whether the alert is visible. This will be true after |-start| is called | ||
// until a subsequent |-stop|. | ||
@property(nonatomic, readonly, getter=isVisible) BOOL visible; | ||
|
||
- (instancetype)initWithBaseViewController:(UIViewController*)viewController | ||
NS_UNAVAILABLE; | ||
|
||
// Init a coordinator for displaying a alert on this view controller. If | ||
// |-configureForActionSheetWithRect:popoverView:| is not called, it will be a | ||
// modal alert. | ||
- (instancetype)initWithBaseViewController:(UIViewController*)viewController | ||
title:(NSString*)title | ||
NS_DESIGNATED_INITIALIZER; | ||
|
||
// Call this before adding any button to change the alert to an action sheet. | ||
- (void)configureForActionSheetWithRect:(CGRect)rect popoverView:(UIView*)view; | ||
|
||
// Adds an item at the end of the menu. It does nothing if |visible| is true or | ||
// if trying to add an item with a UIAlertActionStyleCancel while | ||
// |cancelButtonAdded| is true. | ||
- (void)addItemWithTitle:(NSString*)title | ||
action:(ProceduralBlock)actionBlock | ||
style:(UIAlertActionStyle)style; | ||
|
||
// Returns the number of actions attached to the current alert. | ||
- (NSUInteger)actionsCount; | ||
|
||
@end | ||
|
||
#endif // IOS_CHROME_BROWSER_UI_ALERT_COORDINATOR_ALERT_COORDINATOR_H_ |
159 changes: 159 additions & 0 deletions
159
ios/chrome/browser/ui/alert_coordinator/alert_coordinator.mm
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,159 @@ | ||
// Copyright 2016 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/ui/alert_coordinator/alert_coordinator.h" | ||
|
||
#import "base/ios/weak_nsobject.h" | ||
#import "base/mac/scoped_nsobject.h" | ||
#include "ui/base/l10n/l10n_util.h" | ||
#include "ui/strings/grit/ui_strings.h" | ||
|
||
@interface AlertCoordinator () { | ||
// Variables backing properties of the same name. | ||
base::scoped_nsobject<UIAlertController> _alertController; | ||
base::scoped_nsobject<NSString> _message; | ||
|
||
// Title for the alert. | ||
base::scoped_nsobject<NSString> _title; | ||
// Rectangle for the popover alert. | ||
CGRect _rect; | ||
// View for the popovert alert. | ||
base::scoped_nsobject<UIView> _view; | ||
// Style for this alert. | ||
UIAlertControllerStyle _style; | ||
} | ||
|
||
// Redefined to readwrite. | ||
@property(nonatomic, readwrite, getter=isVisible) BOOL visible; | ||
// Lazy initializer to create the |_alert|. | ||
@property(nonatomic, readonly) UIAlertController* alertController; | ||
|
||
// Called when the alert is dismissed to perform cleanup. | ||
- (void)alertDismissed; | ||
|
||
@end | ||
|
||
@implementation AlertCoordinator | ||
|
||
@synthesize visible = _visible; | ||
@synthesize cancelButtonAdded = _cancelButtonAdded; | ||
|
||
- (instancetype)initWithBaseViewController:(UIViewController*)viewController { | ||
NOTREACHED(); | ||
return nil; | ||
} | ||
|
||
- (instancetype)initWithBaseViewController:(UIViewController*)viewController | ||
title:(NSString*)title { | ||
self = [super initWithBaseViewController:viewController]; | ||
if (self) { | ||
_style = UIAlertControllerStyleAlert; | ||
_title.reset([title copy]); | ||
} | ||
return self; | ||
} | ||
|
||
#pragma mark - Public Methods. | ||
|
||
- (void)configureForActionSheetWithRect:(CGRect)rect popoverView:(UIView*)view { | ||
if (_alertController) | ||
return; | ||
|
||
_style = UIAlertControllerStyleActionSheet; | ||
_view.reset([view retain]); | ||
_rect = rect; | ||
} | ||
|
||
- (void)addItemWithTitle:(NSString*)title | ||
action:(ProceduralBlock)actionBlock | ||
style:(UIAlertActionStyle)style { | ||
if (self.visible || | ||
(style == UIAlertActionStyleCancel && self.cancelButtonAdded)) { | ||
return; | ||
} | ||
|
||
if (style == UIAlertActionStyleCancel) | ||
_cancelButtonAdded = YES; | ||
|
||
base::WeakNSObject<AlertCoordinator> weakSelf(self); | ||
|
||
UIAlertAction* alertAction = | ||
[UIAlertAction actionWithTitle:title | ||
style:style | ||
handler:^(UIAlertAction*) { | ||
[weakSelf alertDismissed]; | ||
if (actionBlock) | ||
actionBlock(); | ||
}]; | ||
|
||
[self.alertController addAction:alertAction]; | ||
} | ||
|
||
- (void)start { | ||
// Check that the view is still visible on screen, otherwise just return and | ||
// don't show the context menu. | ||
if (![self.baseViewController.view window] && | ||
![self.baseViewController.view isKindOfClass:[UIWindow class]]) { | ||
return; | ||
} | ||
|
||
// Display at least one button to let the user dismiss the alert. | ||
if ([self actionsCount] == 0) { | ||
[self addItemWithTitle:l10n_util::GetNSString(IDS_APP_OK) | ||
action:nil | ||
style:UIAlertActionStyleDefault]; | ||
} | ||
|
||
[self.baseViewController presentViewController:self.alertController | ||
animated:YES | ||
completion:nil]; | ||
self.visible = YES; | ||
} | ||
|
||
- (void)stop { | ||
[_alertController dismissViewControllerAnimated:NO completion:nil]; | ||
[self alertDismissed]; | ||
} | ||
|
||
- (NSUInteger)actionsCount { | ||
return [_alertController actions].count; | ||
} | ||
|
||
#pragma mark - Property Implementation. | ||
|
||
- (UIAlertController*)alertController { | ||
if (!_alertController) { | ||
UIAlertController* alert = | ||
[UIAlertController alertControllerWithTitle:_title | ||
message:_message | ||
preferredStyle:_style]; | ||
|
||
if (alert) | ||
_alertController.reset([alert retain]); | ||
|
||
if (_style == UIAlertControllerStyleActionSheet) { | ||
alert.popoverPresentationController.sourceView = _view; | ||
alert.popoverPresentationController.sourceRect = _rect; | ||
} | ||
} | ||
return _alertController; | ||
} | ||
|
||
- (NSString*)message { | ||
return _message; | ||
} | ||
|
||
- (void)setMessage:(NSString*)message { | ||
_message.reset([message copy]); | ||
} | ||
|
||
#pragma mark - Private Methods. | ||
|
||
- (void)alertDismissed { | ||
self.visible = NO; | ||
_cancelButtonAdded = NO; | ||
_alertController.reset(); | ||
} | ||
|
||
@end |
Oops, something went wrong.