3

I want to design a swiftui view MainView() where an interstitial ad will be presented without reloading MainView().

My strategy is:

  1. Load ad from GADInterstitialAd,
  2. Present the ad on a UIViewController(). Then make UIViewControllerRepresentable to be presentable in swiftui.
  3. Present it to the MainView() using fullScreenCover(isPresented: , content: ) modifier.

But every time while the ad presented, the MainView() goes to .onDisappear state, and after closing the ad, it goes to .onAppear state. For that reason the MainView() is fully reloaded. I want to stop this reloading issue. How should I actually present the ad in my view?

Update: Here I have added AdView for more clarification.

struct nterstitialAdView: UIViewControllerRepresentable {
    var interstitialAd: GADInterstitialAd?
    var callback: () -> Void

    func makeUIViewController(context: Context) -> UIViewController {
        let view = UIViewController()
        DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(1)) {
            self.showAd(from: view, callback: callback)
        }
        return view
    }

    func updateUIViewController(_ uiViewController: UIViewController, context: Context) {
    
    }

    func showAd(from root: UIViewController, callback: () -> Void) {
        if let ad = interstitialAd {
            ad.present(fromRootViewController: root)
            callback()
            print(":: Ad Presented")
        } else {
            print(":: Ad not ready")
            callback()
        }
    }
}
Jabed Dhali
  • 167
  • 6
  • Does this answer your question? [How to pass Textfield value to view controller through button click in Swift UI](https://stackoverflow.com/questions/69942854/how-to-pass-textfield-value-to-view-controller-through-button-click-in-swift-ui) – lorem ipsum Jan 11 '23 at 12:36
  • A setup like the link above would help. It also give you control of the ads so you can “pre-load” and then display. – lorem ipsum Jan 11 '23 at 12:37
  • I have preload the ads (interstitial ad), then display using ad.present() for full screen view. But the mainView() then reloaded. – Jabed Dhali Jan 19 '23 at 03:22
  • That is because you are reloading the body with the unnecessary Bool for the cover – lorem ipsum Jan 19 '23 at 10:26

2 Answers2

0

Rather than present using fullScreenCover, how about displaying the ViewController in a ZStack, for example:

struct ContentView: View {
    
    @State private var showAd = false
    
    var body: some View {
        ZStack {
            VStack {
                Text("Main View")
            }
            .task {
                //  Show AdView after a delay
                try? await Task.sleep(nanoseconds: 2_000_000_000)
                showAd = true
            }
            .onAppear {
                print("Appearing") // This is only called once
            }
            
            if showAd {
                AdView {
                    showAd = false
                }
                .edgesIgnoringSafeArea(.all)
            }
        }
    }
}

// Just an example view for testing
struct AdView: UIViewControllerRepresentable {
    
    let dismiss: () -> Void
    
    func makeUIViewController(context: Context) -> UIViewController {
        let vc = UIViewController()
        vc.view.backgroundColor = .red
        let button = UIButton(type: .custom, primaryAction: UIAction(handler: { _ in
            dismiss()
        }))
        button.setTitle("Dismiss", for: .normal)
        button.translatesAutoresizingMaskIntoConstraints = false
        vc.view.addSubview(button)
        vc.view.centerXAnchor.constraint(equalTo: button.centerXAnchor).isActive = true
        vc.view.centerYAnchor.constraint(equalTo: button.centerYAnchor).isActive = true
        return vc
    }
    
    func updateUIViewController(_ uiViewController: UIViewController, context: Context) {
    }
}

It should be pretty straightforward to animate the AdView in, if that's what's required.

Ashley Mills
  • 50,474
  • 16
  • 129
  • 160
  • Using the same logic, when GADInterstitialAd presented, the ContentView reloaded. – Jabed Dhali Jan 14 '23 at 16:48
  • I don't think that this will work. If it worked then anyone could trick Google into presenting invisible view and earning the money that way. – Ivan Ičin Jan 14 '23 at 17:36
0

You can track in a Bool whether your page has already loaded and not reload it if it did.

Other than that The iOS is made to execute OnAppear in that case, that happens both in UIKit and SwiftUI, so even calling UIKit in help won't work.

Ivan Ičin
  • 9,672
  • 5
  • 36
  • 57