iosswiftswiftuiuikittipkit

Swift TipKit MaxDisplayCount doesn't work in UIHostingController on iOS


If you configure simple Tip with MaxDisplayCount option, this option doesn't have any effect when showing TipView in SwiftUI view which is wrapped in UIHostingController. The Tip never invalidates and remains visible until user dismisses it manually.

Tip definition:

struct CustomTip: Tip {
    
    var title: Text {
        Text("Tip title")
    }
    
    var message: Text? {
        Text("Tip message")
    }
    
    var options: [Option] {
        MaxDisplayCount(1)
    }
}

AppDelegate:

import UIKit
import SwiftUI
import TipKit

@main
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        // Override point for customization after application launch.
        
        try? Tips.configure()
        
        let vc = UIHostingController(rootView: CustomView())
        window = UIWindow(frame: UIScreen.main.bounds)
        window?.rootViewController = vc
        window?.makeKeyAndVisible()
        
        return true
    }
}

SwiftUI view:

import SwiftUI
import TipKit

struct CustomView: View {
    var body: some View {
        VStack {
            TipView(CustomTip())
            Text("Hello, World!")
        }
    }
}

Solution

  • I filed a Feedback report and got an answer from Apple stating that this is known issue they are hoping to fix in a future update - claiming it is due to how SwiftUI APIs use scenePhase. Recommended solution for now is to use TipUIView instead of the TipView for displaying the tip.