admin管理员组文章数量:1410737
Note: This question refers to macOS and has nothing to do with iOS.
Context
My Mac app has a "log" window that appears when various parts of the app need to present errors or warnings to the user. In SwiftUI, the abbreviated structure looks like this:
@main
struct SomeApp: App
{
@Environment(\.openWindow) private var openWindow
@State private var appController = AppController()
var body: some Scene
{
Window("SomeApp", id: SomeApp.mainWindowIdentifier) {
MainWindowRootView()
.environment(appController)
}
Window("Log", id: SomeApp.logWindowIdentifier) {
LogWindowRootView()
}
}
}
Question
I know I can use openWindow(id:)
to open the Log window. But what I really want is what I had in an AppKit NSWindowController
:
if showWindow && !(window?.occlusionState.contains(.visible) ?? false)
{
self.showWindow(self)
}
This ensures that if the log window is already partially visible (i.e. the user has it tiled behind some other windows on screen, but at least part of it can be seen) then it doesn't jump to the front and steal focus. It's a small detail, but one that makes the app a MUCH more pleasant citizen of macOS.
Is there a similar way to achieve this in pure SwiftUI? I want the window to open (become key) only if it's fully occluded.
Note: This question refers to macOS and has nothing to do with iOS.
Context
My Mac app has a "log" window that appears when various parts of the app need to present errors or warnings to the user. In SwiftUI, the abbreviated structure looks like this:
@main
struct SomeApp: App
{
@Environment(\.openWindow) private var openWindow
@State private var appController = AppController()
var body: some Scene
{
Window("SomeApp", id: SomeApp.mainWindowIdentifier) {
MainWindowRootView()
.environment(appController)
}
Window("Log", id: SomeApp.logWindowIdentifier) {
LogWindowRootView()
}
}
}
Question
I know I can use openWindow(id:)
to open the Log window. But what I really want is what I had in an AppKit NSWindowController
:
if showWindow && !(window?.occlusionState.contains(.visible) ?? false)
{
self.showWindow(self)
}
This ensures that if the log window is already partially visible (i.e. the user has it tiled behind some other windows on screen, but at least part of it can be seen) then it doesn't jump to the front and steal focus. It's a small detail, but one that makes the app a MUCH more pleasant citizen of macOS.
Is there a similar way to achieve this in pure SwiftUI? I want the window to open (become key) only if it's fully occluded.
Share Improve this question edited Mar 7 at 17:13 Bryan asked Mar 7 at 7:13 BryanBryan 5,8474 gold badges46 silver badges81 bronze badges1 Answer
Reset to default 1Achieving the same behavior as the NSWindowController
in AppKit can be a bit tricky since SwiftUI doesn't provide direct access to window properties like occlusion state.
However, we can try to create a custom NSWindowController
to manage the log window.
import Cocoa
class LogWindowController: NSWindowController {
static let shared = LogWindowController(windowNibName: "LogWindow")
func showIfNeeded() {
if let window = self.window, !window.occlusionState.contains(.visible) {
self.showWindow(nil)
}
}
}
Now, we can create a SwiftUI view to trigger the window controller
import SwiftUI
struct ContentView: View {
var body: some View {
Button("Show Log Window") {
LogWindowController.shared.showIfNeeded()
}
}
}
Integrating with SwiftUI app structure:
@main
struct SomeApp: App {
var body: some Scene {
Window("SomeApp", id: "mainWindow") {
ContentView()
}
}
}
At least, you can control the visibility of the log window without it stealing focus if it's already partially visible.
Again, this is just a work around and it might not be the exact fit. Hope it helps
本文标签: swiftCan I access window occlusionState in a SwiftUI appStack Overflow
版权声明:本文标题:swift - Can I access window occlusionState in a SwiftUI app? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744943890a2633659.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论