ios 如何使用 UIAlertController 替换 UIActionSheet?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/27632614/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to use UIAlertController to replace UIActionSheet?
提问by Don_Chen
I am maintaining an old iOS project which based on SDK 6.0.
我正在维护一个基于 SDK 6.0 的旧 iOS 项目。
A method on this project called
这个项目的一个方法叫做
-(void) showComboBox:(UIView*)view:withOptions:(NSDictionary*)options
-(void) showComboBox:(UIView*)view:withOptions:(NSDictionary*)options
is used to show a combo box. To achieve the goal, it used UIActionSheet, which is deprecated on iOS8.
用于显示组合框。为了实现这个目标,它使用了 UIActionSheet,它在 iOS8 上已被弃用。
My solution is like this:
我的解决方案是这样的:
if (floor(NSFoundationVersionNumber) > NSFoundationVersionNumber10_8) {
UIAlertController* alertController = [UIAlertController
alertControllerWithTitle:@"title"
message:@"message"
preferredStyle:UIAlertControllerStyleActionSheet];
UIAlertAction* item = [UIAlertAction actionWithTitle:@"item"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *action) {
//do something here
//inform the selection to the WebView
...
[alertController dismissViewControllerAnimated:YES completion:nil];
}];
UIAlertAction* cancelAction = [UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
[alertController dismissViewControllerAnimated:YES completion:nil];
}];
[alertController addAction:item];
[alertController addAction:cancelAction];
//I am not sure whether it's the right way
if ([view.nextResponder isKindOfClass:UIViewController.class]) {
UIViewController* vc = (UIViewController*)view.nextResponder;
[vc presentViewController:alertController animated:YES completion:nil];
}
Is that a proper solution?
这是一个适当的解决方案吗?
This is what I mostly concern about: UIAlertController needs to be added to a UIViewController but I can only get the pointer of the UIView, so I used view.nextResponder to get what I want, but it's that a good way?
这就是我最关心的: UIAlertController 需要添加到 UIViewController 但我只能获取 UIView 的指针,所以我使用 view.nextResponder 来获取我想要的东西,但这是一个好方法吗?
回答by Kampai
I have used following code to show action sheet using UIAlertViewController
and it works perfect.
我使用以下代码来显示操作表UIAlertViewController
,并且效果很好。
Swift
迅速
let alert = UIAlertController(title: "Action Title", message: "Action Message", preferredStyle: .actionSheet)
let action = UIAlertAction(title: "Item", style: .default) {
UIAlertAction in
// Write your code here
}
alert.addAction(action)
let cancelAction = UIAlertAction(title: "Cancel", style: .cancel) {
UIAlertAction in
// It will dismiss action sheet
}
alert.addAction(cancelAction)
self.present(alert, animated: true, completion: nil)
Objective C
目标 C
- (IBAction)buttonClicked:(id)sender {
UIAlertController *actionSheet = [UIAlertController alertControllerWithTitle:@"Action Sheet" message:@"Using the alert controller" preferredStyle:UIAlertControllerStyleActionSheet];
[actionSheet addAction:[UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) {
// Cancel button tappped.
[self dismissViewControllerAnimated:YES completion:^{
}];
}]];
[actionSheet addAction:[UIAlertAction actionWithTitle:@"Delete" style:UIAlertActionStyleDestructive handler:^(UIAlertAction *action) {
// Distructive button tapped.
[self dismissViewControllerAnimated:YES completion:^{
}];
}]];
[actionSheet addAction:[UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
// OK button tapped.
[self dismissViewControllerAnimated:YES completion:^{
}];
}]];
// Present action sheet.
[self presentViewController:actionSheet animated:YES completion:nil];
}
Edit:
编辑:
You need to get UIViewController
object here. You can set global variable or call a delegate method, or you can use notification to get view controller object in this code.
你需要在UIViewController
这里得到对象。您可以设置全局变量或调用委托方法,也可以使用通知来获取此代码中的视图控制器对象。
and last line in above code will be like.
上面代码中的最后一行就像。
[self.viewController presentViewController:actionSheet animated:YES completion:nil];
self.viewController
is a global variable which will be set before you actually get this view.
self.viewController
是一个全局变量,它将在您实际获得此视图之前设置。
Because the approach you are following now using view.nextResponder
. I'm afraid that it may not work.
因为您现在遵循的方法使用view.nextResponder
. 恐怕这行不通。
回答by vladicabg
I have used action sheet for changing profile picture. I followed Kampai approach, just removed dismissviewController call since it was kicking me out of a view when pressing Cancel or photo selection view
我已经使用操作表来更改个人资料图片。我遵循了 Kampai 方法,只是删除了dismissviewController 调用,因为它在按取消或照片选择视图时将我踢出视图
UIAlertController *actionSheet = [UIAlertController alertControllerWithTitle:nil message:nil preferredStyle:UIAlertControllerStyleActionSheet];
[actionSheet addAction:[UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) {
// Cancel button tappped do nothing.
}]];
[actionSheet addAction:[UIAlertAction actionWithTitle:@"Take photo" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
// take photo button tapped.
[self takePhoto];
}]];
[actionSheet addAction:[UIAlertAction actionWithTitle:@"Choose photo" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
// choose photo button tapped.
[self choosePhoto];
}]];
[actionSheet addAction:[UIAlertAction actionWithTitle:@"Delete Photo" style:UIAlertActionStyleDestructive handler:^(UIAlertAction *action) {
// Distructive button tapped.
[self deletePhoto];
}]];
回答by Saurabh Yadav
Swift update -
快速更新——
let actionSheet = UIAlertController.init(title: "Please choose a source type", message: nil, preferredStyle: .actionSheet)
actionSheet.addAction(UIAlertAction.init(title: "Take Photo", style: UIAlertActionStyle.default, handler: { (action) in
self.openCamera()
}))
actionSheet.addAction(UIAlertAction.init(title: "Choose Photo", style: UIAlertActionStyle.default, handler: { (action) in
self.showPhotoLibrary()
}))
actionSheet.addAction(UIAlertAction.init(title: "Cancel", style: UIAlertActionStyle.cancel, handler: { (action) in
// self.dismissViewControllerAnimated(true, completion: nil) is not needed, this is handled automatically,
//Plus whatever method you define here, gets called,
//If you tap outside the UIAlertController action buttons area, then also this handler gets called.
}))
//Present the controller
self.present(actionSheet, animated: true, completion: nil)
回答by Sazzad Hissain Khan
Swift 4
斯威夫特 4
let alert = UIAlertController(title: "Select One", message: nil, preferredStyle: UIAlertControllerStyle.actionSheet)
alert.addAction(UIAlertAction(title: "Cancel", style: UIAlertActionStyle.cancel, handler: nil))
alert.addAction(UIAlertAction(title: "Export", style: UIAlertActionStyle.default, handler: { (action) in
// TODO: Export wordlist
}))
alert.addAction(UIAlertAction(title: "Import", style: UIAlertActionStyle.default, handler: { (action) in
// TODO: Import wordlist
}))
self.present(alert, animated: true, completion: nil)
回答by Cynichniy Bandera
While it may look very simple, there is a nasty issue with using UIAlertController
. It is memory leaks prone. In order to test if you have the issue, just put a breakpoint at your view controller's dealloc
method and see if it's deallocated properly.
虽然看起来很简单,但使用UIAlertController
. 它很容易发生内存泄漏。为了测试你是否有问题,只需在你的视图控制器的dealloc
方法上放置一个断点,看看它是否被正确释放。
I was looking for a solution for quite some time and here is how I use an alert controller in my app.
我一直在寻找解决方案,这是我在我的应用程序中使用警报控制器的方法。
+ (void)alertWithPresenting:(UIViewController *)presenting title:(NSString *)title
text:(NSString *)text buttons:(NSArray *)buttons
handler:(void (^)(UIAlertAction *action, NSUInteger index))handler
{
UIAlertController *alert = [UIAlertController
alertControllerWithTitle:title message:text
preferredStyle:UIAlertControllerStyleAlert];
__weak __typeof(alert) weakAlert = alert;
for (NSString *title in buttons) {
UIAlertActionStyle style = UIAlertActionStyleDefault;
if ([title isEqualToString:[L10n cancelButton]])
style = UIAlertActionStyleCancel;
else if ([title isEqualToString:[L10n deleteButton]])
style = UIAlertActionStyleDestructive;
else if ([title isEqualToString:[L10n archiveButton]])
style = UIAlertActionStyleDestructive;
UIAlertAction *action = [UIAlertAction actionWithTitle:title style:style handler:^(UIAlertAction *action) {
if (handler != nil)
handler(action, [buttons indexOfObject:action.title]);
[weakAlert dismissViewControllerAnimated:YES completion:nil];
}];
[alert addAction:action];
}
[presenting presentViewController:alert animated:YES completion:nil];
}
This is not all. Here is an example of how you use it in your view controller. In my case its tableview
with search, so presenting controller may be different.
这还不是全部。这是您如何在视图控制器中使用它的示例。就我而言,它tableview
带有搜索功能,因此呈现控制器可能会有所不同。
- (void) deleteCases:(NSArray *)selectedRows
{
NSString *text = NSLocalizedStringWithDefaultValue(@"cases.delete.alert.text",
@"Localizable", [NSBundle mainBundle],
@"Deleted cases cannot be restored. Continue with delete?",
@"Delete alert text");
NSString *title = NSLocalizedStringWithDefaultValue(@"cases.delete.alert.title",
@"Localizable", [NSBundle mainBundle],
@"Delete cases", @"Detete alert title");
UIViewController *presenting = self.searchController.active ? self.searchController : self;
__weak __typeof(presenting) weakPresenting = presenting;
__weak __typeof(self) weakSelf = self;
[YourClassName alertWithPresenting:weakPresenting title:title text:text
buttons:@[[L10n deleteButton], [L10n cancelButton]]
handler:^(UIAlertAction *action, NSUInteger index)
{
if (action.style == UIAlertActionStyleDestructive) {
__typeof(weakSelf) strongSelf = weakSelf;
// Perform your actions using @strongSelf
}
}];
}
回答by Roman Temchenko
You can use view.window.rootViewController
instead. If you don't care about presenter it is fine.
你可以view.window.rootViewController
改用。如果您不关心演示者,那很好。