SwiftUI equivalent to viewWillTransition event in UIKit?

Hi! In an app implemented using SwiftUI, I want to execute some code when a view changes size. In the previous framework (UIKit), this can be done by using viewWillTransition event in UIViewController, but I cannot find a SwiftUI equivalent now. Do you have an idea how to do that?


More detail of the issue I encountered:

I am following the ADMOB documentation to include adaptive banner ad in the app, and the ADMOB instruction uses the viewWillTransition event

https://developers.google.com/admob/ios/banner/adaptive

I has successfully included a banner app using UIViewRepresentable to wrap the ADMOB object that originally supports UIKit, but just missing the way to respond to layout change of the app (more specifically, rotation).


Thank you!

Answered by ssshhh in 399202022

A solution is figured out: I don't need to use the viewWillTransition event. Below is the code I wrote:


import SwiftUI
import GoogleMobileAds
import UIKit

struct ContentView: View {
    var body: some View {
        VStack(alignment: .leading) {
            AdView().frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: 300).border(Color.red, width: 5)
            }
        .frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity)
            .border(Color.yellow, width: 2)      
    }
}

struct AdView : UIViewRepresentable {
    @State private var banner: GADBannerView = GADBannerView(adSize: kGADAdSizeBanner)
    
    func makeUIView(context: UIViewRepresentableContext<AdView>) -> GADBannerView {
        banner.adUnitID = "ca-app-pub-3940256099942544/2934735716"
        banner.rootViewController = UIApplication.shared.windows.first?.rootViewController
        banner.load(GADRequest())
        return banner
    }
    
    func updateUIView(_ uiView: GADBannerView, context: UIViewRepresentableContext<AdView>) {
        banner.adSize = kGADAdSizeBanner
        banner.load(GADRequest())
    }
}


When the device (in simulator) rotates, the AD size changed.

Accepted Answer

A solution is figured out: I don't need to use the viewWillTransition event. Below is the code I wrote:


import SwiftUI
import GoogleMobileAds
import UIKit

struct ContentView: View {
    var body: some View {
        VStack(alignment: .leading) {
            AdView().frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: 300).border(Color.red, width: 5)
            }
        .frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity)
            .border(Color.yellow, width: 2)      
    }
}

struct AdView : UIViewRepresentable {
    @State private var banner: GADBannerView = GADBannerView(adSize: kGADAdSizeBanner)
    
    func makeUIView(context: UIViewRepresentableContext<AdView>) -> GADBannerView {
        banner.adUnitID = "ca-app-pub-3940256099942544/2934735716"
        banner.rootViewController = UIApplication.shared.windows.first?.rootViewController
        banner.load(GADRequest())
        return banner
    }
    
    func updateUIView(_ uiView: GADBannerView, context: UIViewRepresentableContext<AdView>) {
        banner.adSize = kGADAdSizeBanner
        banner.load(GADRequest())
    }
}


When the device (in simulator) rotates, the AD size changed.

Is there another answer without UIViewRepresentable and support iOS 13.0?

SwiftUI equivalent to viewWillTransition event in UIKit?
 
 
Q