mirror of
https://github.com/bryanthaboi/gen1recomp.git
synced 2026-08-12 08:21:02 +02:00
Merge pull request #728 from hernan0078/ios-picker-dismiss
iOS: a file picker dismissed by swiping locks out every later picker
This commit is contained in:
@@ -174,15 +174,27 @@ public final class GRPickerBridge: NSObject {
|
||||
// Without this the stacked present makes the picker auto-dismiss
|
||||
// with zero documents (observed as didPickDocumentsAt 0 urls)
|
||||
// and the user's pick silently does nothing.
|
||||
guard var top = UIApplication.shared.windows
|
||||
.first(where: { $0.isKeyWindow })?.rootViewController
|
||||
else { return false }
|
||||
// Self-heal before consulting the list. If UIKit is presenting
|
||||
// nothing at all, any delegate still in it belongs to a sheet
|
||||
// that is long gone, and treating it as live would lock the
|
||||
// picker out for the rest of the session. Belt and braces with
|
||||
// the dismissal callback above: that one closes the known hole,
|
||||
// this one closes whatever hole iOS invents next.
|
||||
if top.presentedViewController == nil, !liveDelegates.isEmpty {
|
||||
NSLog("GRPickerBridge: clearing %d stale delegate(s)",
|
||||
liveDelegates.count)
|
||||
liveDelegates.removeAll()
|
||||
}
|
||||
guard liveDelegates.isEmpty else {
|
||||
NSLog("GRPickerBridge: picker already active; ignoring re-present")
|
||||
return true
|
||||
}
|
||||
guard var top = UIApplication.shared.windows
|
||||
.first(where: { $0.isKeyWindow })?.rootViewController
|
||||
else { return false }
|
||||
while let presented = top.presentedViewController { top = presented }
|
||||
picker.delegate = delegate
|
||||
picker.presentationController?.delegate = delegate
|
||||
liveDelegates.append(delegate)
|
||||
delegate.onFinish = { [weak delegate] in
|
||||
liveDelegates.removeAll { $0 === delegate }
|
||||
@@ -197,7 +209,8 @@ public final class GRPickerBridge: NSObject {
|
||||
}
|
||||
}
|
||||
|
||||
private final class PickerDelegate: NSObject, UIDocumentPickerDelegate {
|
||||
private final class PickerDelegate: NSObject, UIDocumentPickerDelegate,
|
||||
UIAdaptivePresentationControllerDelegate {
|
||||
private let onPick: ([URL]) -> Void
|
||||
var onFinish: (() -> Void)?
|
||||
init(onPick: @escaping ([URL]) -> Void) { self.onPick = onPick }
|
||||
@@ -215,4 +228,18 @@ private final class PickerDelegate: NSObject, UIDocumentPickerDelegate {
|
||||
NSLog("GRPickerBridge: picker cancelled")
|
||||
onFinish?()
|
||||
}
|
||||
|
||||
// Swiping the sheet down calls NEITHER of the two above: since iOS 13 an
|
||||
// interactively dismissed picker reports only through the adaptive
|
||||
// presentation delegate. Without this the delegate is never taken out of
|
||||
// liveDelegates, the re-present guard below then swallows every later
|
||||
// picker while still answering true -- so Lua arms its poll and waits for
|
||||
// a file that no sheet is ever going to produce. That is the whole of the
|
||||
// "Import ROM does nothing until you restart the app" report: the restart
|
||||
// is not refreshing anything, it is clearing this array.
|
||||
func presentationControllerDidDismiss(_ presentationController:
|
||||
UIPresentationController) {
|
||||
NSLog("GRPickerBridge: picker dismissed interactively")
|
||||
onFinish?()
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user