Skip to content

Commit 3af7c4d

Browse files
authored
Prevent orphaned views from blocking (#517)
1 parent 4e49214 commit 3af7c4d

File tree

2 files changed

+15
-3
lines changed

2 files changed

+15
-3
lines changed

SwiftMessages/Presenter.swift

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,13 @@ class Presenter: NSObject {
6868
return duration
6969
}
7070

71+
/// Detects the scenario where the view was shown, but the containing view heirarchy was removed before the view
72+
/// was hidden. This unusual scenario could result in the message queue being blocked because the presented
73+
/// view was not properly hidden by SwiftMessages. `isOrphaned` allows the queuing logic to unblock the queue.
74+
var isOrphaned: Bool {
75+
return installed && view.window == nil
76+
}
77+
7178
// MARK: - Constants
7279

7380
enum PresentationContext {
@@ -97,7 +104,7 @@ class Presenter: NSObject {
97104

98105
private weak var delegate: PresenterDelegate?
99106
private var presentationContext = PresentationContext.viewController(Weak<UIViewController>(value: nil))
100-
107+
private var installed = false
101108
private var interactivelyHidden = false;
102109

103110
// MARK: - Showing and hiding
@@ -412,6 +419,7 @@ class Presenter: NSObject {
412419
maskingView.accessibleElements = elements
413420
}
414421

422+
installed = true
415423
guard let containerView = presentationContext.viewValue() else { return }
416424
(presentationContext.viewControllerValue() as? WindowViewController)?.install()
417425
installMaskingView(containerView: containerView)

SwiftMessages/SwiftMessages.swift

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -586,7 +586,10 @@ open class SwiftMessages {
586586
fileprivate func enqueue(presenter: Presenter) {
587587
if presenter.config.ignoreDuplicates {
588588
counts[presenter.id] = (counts[presenter.id] ?? 0) + 1
589-
if _current?.id == presenter.id && _current?.isHiding == false { return }
589+
if let _current,
590+
_current.id == presenter.id,
591+
!_current.isHiding,
592+
!_current.isOrphaned { return }
590593
if queue.filter({ $0.id == presenter.id }).count > 0 { return }
591594
}
592595
func doEnqueue() {
@@ -606,7 +609,8 @@ open class SwiftMessages {
606609
}
607610

608611
fileprivate func dequeueNext() {
609-
guard self._current == nil, queue.count > 0 else { return }
612+
guard queue.count > 0 else { return }
613+
if let _current, !_current.isOrphaned { return }
610614
let current = queue.removeFirst()
611615
self._current = current
612616
// Set `autohideToken` before the animation starts in case

0 commit comments

Comments
 (0)