Skip to content

Commit 18e7a44

Browse files
committed
Fixed folder picker bug in Movie Timecode example project that was introduced in macOS 26
1 parent aa7e97d commit 18e7a44

File tree

1 file changed

+22
-18
lines changed

1 file changed

+22
-18
lines changed

Examples/Movie Timecode/Movie Timecode/Support/OpenPanel.swift

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
import Foundation
1010
import AppKit
11+
import SwiftUI
1112

1213
extension NSOpenPanel {
1314
public convenience init(
@@ -22,31 +23,33 @@ extension NSOpenPanel {
2223
}
2324

2425
public func present(
25-
completion: (_ urls: [URL]?) -> Void
26+
completion: @MainActor @escaping (_ urls: [URL]?) -> Void
2627
) {
2728
var selectedURLs: [URL]?
2829

29-
if runModal() == .OK {
30-
selectedURLs = urls
30+
// runModal() must be called asynchronously or we get a runtime exception on macOS 26
31+
Task { @MainActor in
32+
if runModal() == .OK {
33+
selectedURLs = urls
34+
}
35+
36+
completion(selectedURLs)
3137
}
32-
33-
completion(selectedURLs)
3438
}
3539
}
3640

37-
import SwiftUI
38-
41+
@MainActor
3942
public struct OpenPanelView<Content: View>: View {
4043
@Binding public var isPresented: Bool
4144
public let setup: ((_ panel: NSOpenPanel) -> Void)?
42-
public let completion: (_ urls: [URL]?) -> Void
45+
public let completion: @MainActor (_ urls: [URL]) -> Void
4346
public let content: Content
4447

4548
@State private var panel: NSOpenPanel?
4649

4750
public var body: some View {
4851
content
49-
.onChange(of: isPresented) { oldValue, newValue in
52+
.onChange(of: isPresented) { newValue in
5053
newValue ? present() : close()
5154
}
5255
}
@@ -56,16 +59,17 @@ public struct OpenPanelView<Content: View>: View {
5659
setup?(newPanel)
5760
panel = newPanel
5861

59-
var selectedURLs: [URL]?
60-
6162
isPresented = true
62-
if newPanel.runModal() == .OK {
63-
selectedURLs = newPanel.urls
64-
}
6563

66-
completion(selectedURLs)
67-
panel = nil
68-
isPresented = false
64+
newPanel.present { urls in
65+
isPresented = false
66+
panel = nil
67+
if let urls {
68+
completion(urls)
69+
} else {
70+
// user cancelled or something else happened
71+
}
72+
}
6973
}
7074

7175
private func close() {
@@ -79,7 +83,7 @@ extension View {
7983
public func fileOpenPanel(
8084
isPresented: Binding<Bool>,
8185
setup: ((NSOpenPanel) -> Void)? = nil,
82-
completion: @escaping (_ urls: [URL]?) -> Void
86+
completion: @MainActor @escaping (_ urls: [URL]?) -> Void
8387
) -> some View {
8488
OpenPanelView(
8589
isPresented: isPresented,

0 commit comments

Comments
 (0)