iOS 11/Xcode 9.0 中的 SFSafariViewController 空白

Posted

技术标签:

【中文标题】iOS 11/Xcode 9.0 中的 SFSafariViewController 空白【英文标题】:SFSafariViewController blank in iOS 11/Xcode 9.0 【发布时间】:2017-09-27 03:44:49 【问题描述】:

单击 UIActionSheet 中的按钮会打开一个 SFSafariViewController。它一直运行良好,并且在除 ios 11 之外的所有 iOS 版本上仍然运行良好。关于 iOS 11 或 Xcode 9.0 中的 SFSafariViewController 是否有任何更改可能导致此问题?

更新 - 所以似乎是它的 Xcode 9.0 导致了这个问题。我曾尝试在不同的 iOS 版本上运行它,但它们似乎都出现了这个问题。当我使用 Xcode 8.3.3 运行它时,它曾经可以正常工作,而我不再拥有了 :(

这是代码 -

- (void)presentWebView:(NSString *)url 
url = [url stringByReplacingOccurrencesOfString:@" " withString:@"+"];
url = [url stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSURL *URL = [NSURL URLWithString:url];

if (URL) 
    if ([SFSafariViewController class] != nil) 
        SFSafariViewController *sfvc = [[SFSafariViewController alloc] initWithURL:URL];
        sfvc.delegate = self;
        [self.tabBarController presentViewController:sfvc animated:YES completion:nil];
     else 
        if (![[UIApplication sharedApplication] openURL:URL]) 
            NSLog(@"%@%@",@"Failed to open url:",[url description]);
        
    
 else 
    // will have a nice alert displaying soon.

【问题讨论】:

能不能展示一下你试过的代码,ios11已经修改了 @Anbu.Karthik 添加了代码 【参考方案1】:

我已经设法在我的代码中解决了这个问题。我希望这可以帮助其他有类似问题的人。

我遇到了与这里描述的完全相同的问题。我尝试了上面的所有方法,不幸的是没有任何效果。

在我的应用中有不同的窗口。解决方法是确保显示SFSafariViewController 的窗口在显示之前是“关键”。例如:

class MyViewController: UIViewcontroller 
    func showSafariViewController() 
        // imagine we have 2 windows, one for 'normal' content (key window) and one for 'other' content. lets say we're showing the 'other' content window, and have hidden the 'normal' window. you can see the 'other' content window in the app, but it won't be the key window!
        let window = // get the 'other' content window

        // make sure we make it the key window before presenting safari
        window.makeKey()

        // now present safari and celebrate victory by triumphantly slurping on your hot black coffee
        let mySafariViewController = SFSafariViewController(...)
        self.present(mySafariViewController ...)
    

我怀疑 Apple 正在窗口 UIApplication.shared.keyWindow 中搜索 SFSafariViewController 实例。也许他们正在从其他地方添加子视图。在文档中它声明The user's activity and interaction with SFSafariViewController are not visible to your app,所以也许它的错误与增加的安全级别有关https://developer.apple.com/documentation/safariservices/sfsafariviewcontroller

【讨论】:

这解决了我的问题!谢谢! PS:您可以使用UIApplication.shared.windows[0] 轻松获取根窗口(也许这会对某人有所帮助) 我正在使用建议的方法,但遇到问题 - 对 的开始/结束外观转换的不平衡调用。 @Apple 不幸的是,如果没有看到任何代码,我不确定该建议什么 - 这可能有一些与该线程无关的原因。可能值得开始一个新线程?否则也许读这个,看看它是否有帮助***.com/questions/9088465/…【参考方案2】:

我已经尝试使用延迟来完成它并查看控制器加载。两者都为我工作。

方法一。使用延迟。

DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) 
      let controller = SFSafariViewController(url: url)
      controller.modalPresentationStyle = .overFullScreen
      self.present(controller, animated: true, completion: nil)
      controller.delegate = self
    

方法二。加载视图。

      let controller = SFSafariViewController(url: url)
      let _ = controller.view
      controller.modalPresentationStyle = .overFullScreen
      self.present(controller, animated: true, completion: nil)
      controller.delegate = self

【讨论】:

方法二使用 Xcode 11 修复了 iOS 12 上的问题。该问题未出现在 iOS 13 上。【参考方案3】:

非常类似于https://openradar.appspot.com/29108332

要修复它,您可以禁用视图的延迟加载:

SFSafariViewController *viewController = [[SFSafariViewController alloc] init...];
(void)viewController.view;
...
[controller presentViewController:viewController animated:YES completion:nil];

【讨论】:

顺便说一句 - (void)viewController.view; - 做吗? 这会导致视图加载:"If you access this property and its value is currently nil, the view controller automatically calls the loadView() method and returns the resulting view." 为我工作!!【参考方案4】:

更新

原来旧答案不起作用,自从我设置断点后它就起作用了。如果我添加了一个线程睡眠似乎它在 XCode9 中有效,但这不是最好的解决方案。谁有其他更好的解决方案?

SFSafariViewController *sfcontroller = [[SFSafariViewController alloc] initWithURL:url];
if (@available(iOS 11.0, *)) 
    [NSThread sleepForTimeInterval:0.5f];

sfcontroller.delegate = self;
[controller presentViewController:sfcontroller animated:NO completion:nil];

旧答案

我遇到了与 genaks 相同的问题,并修改了 SFViewController。

似乎这段代码对我有用

SFSafariViewController *sfcontroller = [[SFSafariViewController alloc] initWithURL:url];
if (@available(iOS 11.0, *)) 
    SFSafariViewControllerConfiguration *config = [[SFSafariViewControllerConfiguration alloc] init];
    config.barCollapsingEnabled = NO;
    sfcontroller = [[SFSafariViewController alloc] initWithURL:url configuration: config];
 else 
    // Fallback on earlier versions


sfcontroller.delegate = self;

[controller presentViewController:sfcontroller animated:YES completion:nil];

在 ios 11 中,他们引入了 SFSafariViewControllerConfiguration,默认情况下 barCollapsingEnabled 为 true,这似乎是导致我的 SafariView 空白的原因。希望这也能解决你的问题

【讨论】:

有效,但就像你说的那样不是一个好的解决方案。顺便说一句,那个 0.5 有什么神奇之处,因为我尝试减少它但没有用。 工作一次后,这也停止了工作。 SafariViewController 仍然是空白的 如果我需要动画怎么办?【参考方案5】:

我们遇到了这个问题:我们的 URL 是 https://our-side.com/index.html(一个将重定向到 /account 路由的 Angular 站点)。当我们删除index.html 时,SFSafariViewController 加载正确!

【讨论】:

【参考方案6】:

到目前为止对我来说唯一有效的方法是通过以下方式使 SafariViewController 成为 rootviewcontroller -

    ((XYZAppDelegate *)[UIApplication sharedApplication].delegate).window.rootViewController = self.svc;
    [((XYZAppDelegate *)[UIApplication sharedApplication].delegate).window makeKeyAndVisible];

【讨论】:

即使它有效 - 将 rootViewController 替换为仅显示 SFSafariViewController 是完全不正确的

以上是关于iOS 11/Xcode 9.0 中的 SFSafariViewController 空白的主要内容,如果未能解决你的问题,请参考以下文章

在 iOS 9.0 中开始获取 EXC_BAD_ACCESS(点击表格视图中的单元格时)

XCUIApplication 仅适用于 iOS 9.0 或更新版本,swift3

如何在 iOS 9.0 中将图像保存到特定文件夹中

在 iOS 9.0 之前,只有自定义 segues 支持类名

Xcode 9.0 报错,Safe Area Layout Guide Before IOS 9.0

iOS 9.0 Xcode 8.3.3 MfiBtPrinterConnection.h streming 蓝牙 maxLength Zebra ZQ520