Andrew
Andrew

Reputation: 11362

SwiftUI: way to check that WINDOW(not app) activated (become foreground)

I need to call some method on event when my app become foreground

(I'm using ViewModel for each view, so I can call sth not only from view)

As example:

  1. my app is runned;

  2. changed foreground window to Safari app.

  3. Changed foreground window to my app -> some method called.

With .onChange(of: scenePhase) -> .active nothing happens with this scenario

so those code is not solution for me:

struct ContentView: View {
    @Environment(\.scenePhase) private var scenePhase
    var body: some View {
        TestView()
            .onChange(of: scenePhase) { phase in
                switch phase {
                    case .active:
                        print("App is active")
                    default:
                        break
                }
            }
    }
}

Upvotes: 4

Views: 2073

Answers (2)

Andrew
Andrew

Reputation: 11362

Way 1:

(better)

You can use custom AppDelegate with function applicationDidBecomeActive

main app file:

import SwiftUI

@main
struct FileBoApp: App {
//SOLUTION p1
    @NSApplicationDelegateAdaptor(AppDelegate.self) var appDelegate : AppDelegate
//END SOLUTION p1
    
    var body: some Scene {
        /// bla bla bla
    }
}

appDelegate file:

import Foundation
import SwiftUI

//SOLUTION p2
class AppDelegate: NSObject, NSApplicationDelegate {
    func applicationDidBecomeActive(_ notification: Notification) {
       print("FUUUUUUUUUUUU")
    }
}
//END SOLUTION p2

==============================================


Way 2:

( alternative )

    @SceneBuilder var body: some Scene {
        WindowGroup {
            SomeView()
//SOLUTION
                .onReceive(NotificationCenter.default.publisher(for: NSApplication.didBecomeActiveNotification)) { (_) in
                          print("FUUUUUUUUUUUU")
                        }
//END SOLUTION
            
        }

Upvotes: 5

user1046037
user1046037

Reputation: 17735

You could use the environment variable controlActiveState as follows:

@Environment(\.controlActiveState) var controlActiveState

Upvotes: 8

Related Questions