简体   繁体   中英

Main view reloading while showing intersitital ad in swiftui

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()
        }
    }
}

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM