SFSafariViewController as childViewController overlapping view problem

Hello guys,


I've found an interesting issue which maybe my fault, but to fulfill the business requirements I needed to add SFSafariViewController as a child view controller.


The problem is basically the left side of the screen is not responding for touch events. Its only 41 points wide but I've got a bug report about it, because half of the done button is not respond for touch events.


You can see the view hierarchy here. _UIRemoteView has a few subviews on the left side of the screen which are blocking the half of the Done button.

https://snipboard.io/ExMWYH.jpg


The goal is to have Safari on the top of my VC before I even show this VC.

I've made a test project to demonstrate it.

It contains

- a ParentViewController class which is the first view controller in a navigation controller that the app displays.

- and a ViewController class which push itself to parentVC's navigation controller (basically after a delay but it is not related to this problem)


//  ParentViewController.swift
import UIKit
class ParentViewController: UIViewController {
    var sfTestVc: ViewController!
    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        sfTestVc = ViewController()
        sfTestVc.testParent = self
        sfTestVc.delayedLoad()
    }
}

//  ViewController.swift
import UIKit
import SafariServices
import WebKit
import SnapKit

class ViewController: UIViewController {
    func delayedLoad() {
//        DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(400)) {
            self.openSafari()
//        }
    }

    func openSafari() {
        let url = URL(string: "https://apple.com")!
        safari = SFSafariViewController(url: url)
        safari.delegate = self
        self.view.addSubview(safari.view)
        self.addChild(safari)
//        safari.view.frame = self.view.bounds
//        safari.view.autoresizingMask = [.flexibleHeight, .flexibleWidth]
//        safari.view.autoresizesSubviews = true

        safari.didMove(toParent: self)
        safari.view.snp.makeConstraints{ (make) -> Void in
            make.edges.equalTo(self.view)
        }
        // calling delegate about this happend and push this viewcontroller in successVC's navi controller
        self.testParent.navigationController?.pushViewController(self, animated: true)
    }


}

extension ViewController: SFSafariViewControllerDelegate {

}


Do you have any suggestions?

I really want to have safari on the top of my viewController before I start to display my view controller

Replies

//

// ViewController.swift

// TestSafariVC

//

// Created by Amit Dhadse on 14/02/20.

// Copyright © 2020 Amit Dhadse. All rights reserved.

//


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: 30).isActive = true

self.safariVC.view.bottomAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.bottomAnchor, constant: -30).isActive = true

self.safariVC.view.leadingAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.leadingAnchor, constant: 30).isActive = true

self.safariVC.view.trailingAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.trailingAnchor, constant: -30).isActive = true


}

}




Hey KaBlaize...

Sorry man not understand your problem in deapth..may this small help will trigger something for you..

Here what I did is..simple add SafariViewController as childview and set contraints to safariviewcontroller.

Hope it will help..


Thanks,

Amit

I had exactly the same problem. The issue is that you are pushing the SFSafariViewController to a UINavigationController.

Instead present it (and it will also be pushed on the NavigationController, as you want to have it) but without the overlay issue so that the Done button is not covered anymore!

Code Block
let vc = SFSafariViewController(url: URL(string: "anyURL")!)
self.present(vc, animated: true) // will push on a navigationController (when self is already presented by a NavigationController(