Last active
November 24, 2023 05:24
-
-
Save justinyanme/76d9cecd15e991e6afca2c747c772620 to your computer and use it in GitHub Desktop.
SwiftUI Notes 03
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import SwiftUI | |
import AppKit | |
extension View { | |
public func inject<SomeView>(_ view: SomeView) -> some View where SomeView: View { | |
overlay(view.frame(width: 0, height: 0)) | |
} | |
func getWindow(window: @escaping (_ window: NSWindow?) -> Void) -> some View { | |
inject(IntrospectWindowViewRepresentable(getWindow: window)) | |
} | |
} | |
struct IntrospectWindowViewRepresentable: NSViewRepresentable { | |
let getWindow: (_ window: NSWindow?) -> Void | |
init(getWindow: @escaping (_: NSWindow?) -> Void) { | |
self.getWindow = getWindow | |
} | |
func makeNSView(context: Context) -> some NSView { | |
let view = IntrospectWindowView(getWindow: self.getWindow) | |
return view | |
} | |
func updateNSView(_ nsView: NSViewType, context: Context) { | |
// self.getWindow(window: ) | |
} | |
} | |
class IntrospectWindowView: NSView { | |
let getWindow: (_ window: NSWindow?) -> Void | |
init(getWindow: @escaping (_: NSWindow?) -> Void) { | |
self.getWindow = getWindow | |
super.init(frame: .zero) | |
} | |
@available(*, unavailable) | |
required init?(coder _: NSCoder) { | |
fatalError("Create this view programmatically.") | |
} | |
override func viewDidMoveToWindow() { | |
super.viewDidMoveToWindow() | |
DispatchQueue.main.async { | |
self.getWindow(self.window) | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Sample Code for Blog Post: How to access window from SwiftUI view?(Chinese) -> https://justinyan.me/post/5656 | |
final class MainWindowController: NSWindowController { | |
private var mainViewModel: MainViewModel? = nil | |
convenience init() { | |
let window = NSWindow.centeredWindow(size: .zero) | |
let mainViewModel = MainViewModel() | |
let mainView: MainView = MainView(viewModel: mainViewModel) | |
window.contentViewController = NSHostingController(rootView: mainView) | |
window.centerNatural() | |
window.toolbarStyle = .unifiedCompact | |
window.styleMask = [.closable, .miniaturizable, .unifiedTitleAndToolbar, .titled, .fullSizeContentView] | |
window.titlebarAppearsTransparent = true | |
self.init(window: window) | |
self.mainViewModel = mainViewModel | |
NSApp.activate(ignoringOtherApps: false) | |
window.makeKeyAndOrderFront(nil) | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Sample Code for Blog Post: How to access window from SwiftUI view?(Chinese) -> https://justinyan.me/post/5656 | |
// WindowReader source code From project -> https://github.com/aheze/Popovers | |
import Foundation | |
import AppKit | |
import SwiftUI | |
public struct WindowReader<Content: View>: View { | |
/// Your SwiftUI view. | |
public let view: (NSWindow?) -> Content | |
/// The read window. | |
@StateObject var windowViewModel = WindowViewModel() | |
/// Reads the `NSWindow` that hosts some SwiftUI content. | |
public init(@ViewBuilder view: @escaping (NSWindow?) -> Content) { | |
self.view = view | |
} | |
public var body: some View { | |
view(windowViewModel.window) | |
// .id(windowViewModel.window) | |
.background( | |
WindowViewRepresentable(windowViewModel: windowViewModel) | |
) | |
} | |
/// A wrapper view to read the parent window. | |
private struct WindowViewRepresentable: NSViewRepresentable { | |
@ObservedObject var windowViewModel: WindowViewModel | |
func makeNSView(context _: Context) -> WindowView { | |
return WindowView(windowViewModel: self.windowViewModel) | |
} | |
func updateNSView(_: WindowView, context _: Context) {} | |
} | |
private class WindowView: NSView { | |
var windowViewModel: WindowViewModel | |
init(windowViewModel: WindowViewModel) { | |
self.windowViewModel = windowViewModel | |
super.init(frame: .zero) | |
} | |
@available(*, unavailable) | |
required init?(coder _: NSCoder) { | |
fatalError("Should not init with coder") | |
} | |
override func viewDidMoveToWindow() { | |
super.viewDidMoveToWindow() | |
DispatchQueue.main.async { | |
/// Set the window. | |
self.windowViewModel.window = self.window | |
} | |
} | |
} | |
} | |
class WindowViewModel: ObservableObject { | |
@Published var window: NSWindow? | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment