如何在UIView

时间:2018-03-05 06:10:19

标签: ios swift uiwebview webkit sfsafariviewcontroller

我有一个自定义UIView,它有一个按钮属性,我想添加一个动作来打开webview in-app。为此,我想使用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方法在点击" Done"之后关闭视图。按钮。当我在UIView中或任何想法将这个动作连接到我的主控制器以使用正确的方法时,是否有任何动作?

3 个答案:

答案 0 :(得分:3)

这样做,

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

答案 1 :(得分: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
    }

}

enter image description here

答案 2 :(得分:1)

我不这么认为。 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将会很重,这是不好的。