ios 从 iOS8 - iOS11 中的操作表委托以模态方式呈现视图控制器

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/24854802/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 01:28:21  来源:igfitidea点击:

Presenting a view controller modally from an action sheet's delegate in iOS8 - iOS11

iosuikituiactionsheetuialertcontroller

提问by Leo Natan

So I noticed that in iOS8 beta 3 (Update: still happens in iOS 11.2) on iPad, when attempting to present a view controller from within a delegate method of a UIActionSheet, "nothing" happens and a log message is output to the debug console, stating that presentation was attempted while transitioning an alert controller:

所以我注意到在 iPad 上的 iOS8 beta 3(更新:仍然发生在 iOS 11.2)中,当尝试从 a 的委托方法中呈现视图控制器时UIActionSheet,“没有”发生并且日志消息输出到调试控制台,声明在转换警报控制器时尝试了演示:

Warning: Attempt to present <UIViewController: 0x...> on <ViewController: 0x...> which is already presenting <UIAlertController: 0x...>

回答by Leo Natan

Update:As of iOS 9 SDK, UIActionSheetis deprecated, so do not expect a fix regarding this issue. It is best to start using UIAlertControllerwhen possible.

更新:自 iOS 9 SDK 起,UIActionSheet已弃用,因此不要指望有关此问题的修复。最好UIAlertController在可能的情况下开始使用。



The problem seems to come from Apple's switch to using UIAlertControllerinternally to implement the functionality of alert views and action sheets. The issue is seen mostly on iPad and action sheets, because on iPad, action sheets are presented as a popover within a specified view, and what Apple does is travel the responder chain until it finds a view controller and calls presentViewController:animated:completion:with the internal UIAlertController. The problem is less obvious on iPhone and with alert views, because there Apple actually creates a separate window, an empty view controller and presents the internal UIAlertControlleron top of that, so it seems to not interfere with other presentation.

问题似乎来自 Apple 转而使用UIAlertController内部来实现警报视图和操作表的功能。这个问题主要出现在 iPad 和操作表上,因为在 iPad 上,操作表在指定视图中显示为一个弹出框,Apple 所做的是遍历响应者链,直到它找到一个视图控制器并调用presentViewController:animated:completion:内部UIAlertController. 这个问题在 iPhone 和警报视图上不太明显,因为苹果实际上创建了一个单独的窗口,一个空的视图控制器,并UIAlertController在其之上呈现内部,所以它似乎不会干扰其他呈现。

I have opened bug report for this issue: rdar://17742017. Please duplicate it and let Apple know this is a problem.

我已经为此问题打开了错误报告:rdar://17742017。请复制它并让 Apple 知道这是一个问题。

As a workaround, I recommend delaying the presentation until the next runloop, using the following method:

作为一种解决方法,我建议使用以下方法将演示文稿延迟到下一个运行循环:

dispatch_async(dispatch_get_main_queue(), ^ {
    [self presentViewController:vc animated:YES completion:nil];
});

回答by Kjuly

You can try to do your job (presenting view controller) in

您可以尝试在

- (void)      actionSheet:(UIActionSheet *)actionSheet
didDismissWithButtonIndex:(NSInteger)buttonIndex {}

instead of

代替

- (void) actionSheet:(UIActionSheet *)actionSheet
clickedButtonAtIndex:(NSInteger)buttonIndex {}

as @LeoNatan said, "The problem seems to come from Apple's switch to using UIAlertController internally to implement the functionality of alert views and action sheets". So you must to wait the action sheet dismissed, then present the view controller you want.

正如@LeoNatan 所说,“问题似乎来自 Apple 转而在内部使用 UIAlertController 来实现警报视图和操作表的功能”。因此,您必须等待操作表关闭,然后呈现您想要的视图控制器。

@LeoNatan's solution just block the UI at main thread, so it'll also make sure the view controller will be presented after the action sheet was dismissed.

@LeoNatan 的解决方案只是在主线程阻止 UI,因此它还将确保在取消操作表后显示视图控制器。

回答by Achille

unfortunately this code doesn't work for me, I think because my problem was not calling presentController method directly but in the prepareForSegue method so using

不幸的是,这段代码对我不起作用,我想是因为我的问题不是直接调用 presentController 方法,而是在 prepareForSegue 方法中,所以使用

[segue destinationViewController]

I've noticed that if the segue is "push" kind all works correctly, but if it is "modal", just in ipad, i got that error.

我注意到,如果 segue 是“push”类型,一切正常,但如果它是“modal”,就在 ipad 中,我得到了那个错误。

Then I've found some new option in storyboard in the segue panel, and i sovled my problem choosing "Current context" for Presentation option

然后我在 segue 面板的故事板中找到了一些新选项,我解决了为演示选项选择“当前上下文”的问题

I hope this will be helpful for someone else... here is the screenshot about the option

我希望这对其他人有帮助...这是有关该选项的屏幕截图

enter image description here

在此处输入图片说明

回答by Joan Cardona

I fixed it in Swift 3 with the following code

我使用以下代码在 Swift 3 中修复了它

  DispatchQueue.main.async {
            self.present(alertController, animated: true, completion: nil)
        }

回答by Kaey

I had this same issue. I created a separate window for alerts and actionsheets in my appdelegate and presented the alerts on it. It worked for me!

我有同样的问题。我在我的 appdelegate 中为警报和操作表创建了一个单独的窗口,并在其上显示了警报。它对我有用!

   self.alertWindow = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
  // Override point for customization after application launch.
  self.alertWindow.backgroundColor = [UIColor clearColor];
  UIViewController *dummy = [[UIViewController alloc] init];
  [self.alertWindow setRootViewController:dummy];

You can present as :

您可以表示为:

[[myAppDelegate appDelegate].alertWindow makeKeyAndVisible];
  [[myAppDelegate appDelegate].alertWindow.rootViewController presentViewController:alertController animated:YES completion:nil];

回答by Salvador

Issuing a

发行一个

[self.navigationController dismissViewControllerAnimated:YES completion:nil];

on

- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex 

before trying to present another modal view worked for me.

在尝试呈现另一个对我有用的模态视图之前。

回答by zurakach

use

- (void)actionSheet:(UIActionSheet *)actionSheet didDismissWithButtonIndex:(NSInteger)buttonIndex

instead of

代替

- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex

Action view is presented above current VC so thats what causes warning/error. when didDismiss is called, action view is already dismissed, so no problems at all :))

操作视图显示在当前 VC 上方,这就是导致警告/错误的原因。当 didDismiss 被调用时,动作视图已经被解除,所以根本没有问题:))

回答by Tim

Try

尝试

[[NSOperationQueue mainQueue] addOperationWithBlock:^{
    // action sheet presentation
    // or modal view controller presentation
    // or alert view presentation
}];

回答by Pankaj purohit

In iOS 8 Apple uses UIAlertController internally to implement the functionality of alert views and action sheets. So when you want to show a UIViewController modally after displaying UIActionSheet or UIAlertView in delegate method like

在 iOS 8 中,Apple 在内部使用 UIAlertController 来实现警报视图和操作表的功能。因此,当您想在像这样的委托方法中显示 UIActionSheet 或 UIAlertView 后以模态方式显示 UIViewController 时

(void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex

and

(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex

you have to first dismiss UIAlertController as follows:

你必须首先关闭 UIAlertController 如下:

if(SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"8.0"))
{
    UIViewController *vc = [[[[UIApplication sharedApplication] delegate] window] rootViewController];
    [vc dismissViewControllerAnimated:NO completion:^{

    }];
}

Now you can present a modal UIViewController in iOS 8.

现在你可以在 iOS 8 中呈现一个模态 UIViewController。