如何在UIView中呈现SFSafariViewController

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在UIView中呈现SFSafariViewController相关的知识,希望对你有一定的参考价值。

我有一个自定义UIView有一个按钮属性,我想添加一个动作,以打开应用程序中的webview。为此,我想使用SFSafariViewController。以下是我试图实现这一目标的方法。

import UIKit
import SafariServices

class CustomViewScreen: UIView, SFSafariViewControllerDelegate {

@IBAction func privacyNoteBtnAction(_ sender: UIButton) {
    if #available(ios 9.0, *) {
        let urlString = "https://stackoverflow.com/"
        if let url = URL(string: urlString) {
            let vc = SFSafariViewController(url: url, entersReaderIfAvailable: true)
            vc.delegate = self
           UIApplication.shared.keyWindow?.rootViewController?.present(vc, animated: true, completion: nil)
        }
    } else {
        // Fallback on earlier versions
    }
}

func safariViewControllerDidFinish(_ controller: SFSafariViewController) { 
  controller .dismiss(animated: true, completion: nil) // also not able to trigger this method when i tap "Done"
}

我甚至无法使用这种方式,因为我得到“他的观点不在窗口层次中!”此外,我无法在点击“完成”按钮后调用SFSafariViewControllerDelegate方法来关闭视图。当我在UIView中或任何想法将这个动作连接到我的主控制器以使用正确的方法时,是否有任何动作?

答案

这样做,

@IBAction func privacyNoteBtnAction(_ sender: UIButton) {
   if #available(iOS 9.0, *) {
    let urlString = "https://stackoverflow.com/"
    if let url = URL(string: urlString) {
        let vc = SFSafariViewController(url: url, entersReaderIfAvailable: true)
        vc.delegate = self

       if var topController = UIApplication.shared.keyWindow?.rootViewController {
          while let presentedViewController = topController.presentedViewController {
              topController = presentedViewController
          }

          topController.present(vc, animated: true, completion: nil)
       }

    }
} else {
    // Fallback on earlier versions
}
}
另一答案

我不这么认为。 UIView无法呈现视图控制器,因为它们是不同的。您只能在viewcontroller中显示viewcontroller。

所以我建议你的视图只是获取触摸事件,并委托给viewcontroller,告诉它呈现一个SFSafariViewController。像这样:

// view.h
@protocol AccountBindingDelegate <NSObject>
- (void)jumpWebVC:(UIButton*)sender;
@end
@interface CustomRegisterView : UIView
@property (nonatomic, weak) id<AccountBindingDelegate> delegate;
@end

// view.m
[agreementBtn addTarget:self action:@selector(agreementBtnClick:) forControlEvents:UIControlEventTouchUpInside];

- (void)agreementBtnClick:(UIButton*)sender
{
    if (self.delegate && [self.delegate respondsToSelector:@selector(jumpWebVC:)]) {
        [self.delegate jumpWebVC:sender];
    }
}

// code in controller
@interface uiviewContrller ()<AccountBindingDelegate> 

@end

- (void)viewDidLoad {
    _registerView.delegate = self;
}

//tell viewcontroller to present
- (void)jumpWebVC:(UIButton*)sender
{
    PSMFWebVC *webVC = [PSMFWebVC new];
    [self.navigationController pushViewController:webVC animated:YES];
}

UIView不需要知道url,他只是告诉viewcontroller:uiview中的一些按钮已被点击。如果你的uivew有很多按钮,你的CustomViewScreen会很重,这是不好的。

以上是关于如何在UIView中呈现SFSafariViewController的主要内容,如果未能解决你的问题,请参考以下文章

如何从 UITableViewCell 呈现 UIView

如何拍摄未呈现的 UIView 的快照?

呈现 UIView 的最少代码

测量CPU使用率,在Xcode中呈现UIView

为啥我的 UIView 子视图没有在父视图中呈现? (附代码)

iOS 14 从 UIView 呈现 UIMenu