【问题标题】:How to present SFSafariViewController in UIView如何在 UIView 中呈现 SFSafariViewController
【发布时间】:2018-03-05 06:10:19
【问题描述】:

我有一个具有按钮属性的自定义 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 中时有什么想法可以采取行动,或者有什么想法可以将此动作连接到我的主控制器以使用正确的呈现方法?

【问题讨论】:

  • 你只能在另一个视图控制器上呈现视图控制器......你不能在视图中呈现视图控制器......相反你可以添加其他视图控制器的子视图......跨度>
  • 发生了什么self.present(

标签: ios swift uiwebview webkit sfsafariviewcontroller


【解决方案1】:

这样做,

@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
}
}

【讨论】:

    【解决方案2】:
    import UIKit
    import SafariServices
    
    class ViewController: UIViewController {
    
        var safariVC = SFSafariViewController(url: URL(string: "https://apple.com")!)
        
        override func viewDidLoad() {
            super.viewDidLoad()
            addViewControllerAsChildViewController()
        }
        
        //firstVCIdentifier
        
        func addViewControllerAsChildViewController() {
            addChild(safariVC)
            self.view.addSubview(safariVC.view)
            safariVC.didMove(toParent: self)
            self.setUpConstraints()
        }
        
        func setUpConstraints() {
            self.safariVC.view.translatesAutoresizingMaskIntoConstraints = false
            self.safariVC.view.topAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.topAnchor, constant: 100).isActive = true
            self.safariVC.view.bottomAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.bottomAnchor, constant: -100).isActive = true
            self.safariVC.view.leadingAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.leadingAnchor, constant: 100).isActive = true
            self.safariVC.view.trailingAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.trailingAnchor, constant: -100).isActive = true
        }
    
    }
    

    【讨论】:

      【解决方案3】:

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

      所以我建议你的视图只获取触摸事件,并委托给 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 会很重,这不好。

      【讨论】:

        猜你喜欢
        • 2018-08-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-01-27
        • 1970-01-01
        相关资源
        最近更新 更多