Skip to content

Commit 9758ecf

Browse files
authored
Access local window instead of via UIApplication or UIApplicationDelegate (#25672)
* Dismiss the presented controller via the in-scope presenter The quick-action handler already holds the shared presenter; use its rootViewController to dismiss rather than reaching for the app delegate's window. * Read the featured image safe-area inset from the view's own window * Host the appearance-change transition on the settings view's own window * Read the footer safe-area inset from the view's own window * Host the milestone confetti on the view's own window * Block interaction on the connection view's own window during loading * Resolve the debug menu's host window from its own gesture * Remove the loading functions in JetpackConnectionViewController * Remove unused ReaderDetailFeaturedImageView
1 parent 4c65642 commit 9758ecf

7 files changed

Lines changed: 23 additions & 496 deletions

File tree

WordPress/Classes/System/3D Touch/WP3DTouchShortcutHandler.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,22 +29,22 @@ open class WP3DTouchShortcutHandler: NSObject {
2929
return true
3030
case ShortcutIdentifier.Stats.type:
3131
WPAnalytics.track(.shortcutStats)
32-
clearCurrentViewController()
32+
clearCurrentViewController(rootViewPresenter.rootViewController)
3333
if let mainBlog = Blog.lastUsedOrFirst(in: ContextManager.shared.mainContext) {
3434
rootViewPresenter.showStats(for: mainBlog, source: .shortcut)
3535
}
3636
return true
3737
case ShortcutIdentifier.Notifications.type:
3838
WPAnalytics.track(.shortcutNotifications)
39-
clearCurrentViewController()
39+
clearCurrentViewController(rootViewPresenter.rootViewController)
4040
rootViewPresenter.showNotificationsTab()
4141
return true
4242
default:
4343
return false
4444
}
4545
}
4646

47-
fileprivate func clearCurrentViewController() {
48-
WordPressAppDelegate.shared?.window?.rootViewController?.dismiss(animated: false)
47+
fileprivate func clearCurrentViewController(_ rootViewController: UIViewController) {
48+
rootViewController.dismiss(animated: false)
4949
}
5050
}

WordPress/Classes/ViewRelated/Gutenberg/Collapsable Header/CollapsableHeaderViewController.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ class CollapsableHeaderViewController: UIViewController, NoResultsViewHost {
110110
private var footerHeight: CGFloat {
111111
let verticalMargins: CGFloat = 16
112112
let buttonHeight: CGFloat = 44
113-
let safeArea = (UIApplication.shared.mainWindow?.safeAreaInsets.bottom ?? 0)
113+
let safeArea = (view.window?.safeAreaInsets.bottom ?? 0)
114114

115115
var height = verticalMargins + buttonHeight + verticalMargins + safeArea
116116

WordPress/Classes/ViewRelated/Jetpack/Jetpack Settings/JetpackConnectionViewController.swift

Lines changed: 12 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -120,11 +120,19 @@ open class JetpackConnectionViewController: UITableViewController {
120120

121121
@objc func disconnectJetpack() {
122122
WPAnalytics.trackEvent(.jetpackDisconnectRequested)
123-
startLoading()
123+
124+
// Block user interactions while disconnecting, since navigating away from this view controller
125+
// during the process can leave the application in an undetermined state. Capture the window now
126+
// so it can be re-enabled even if `view.window` becomes nil after the view controller is dismissed.
127+
activityIndicatorView.startAnimating()
128+
let window = view.window
129+
window?.isUserInteractionEnabled = false
130+
124131
self.service.disconnectJetpackFromBlog(
125132
self.blog,
126133
success: { [weak self] in
127-
self?.stopLoading()
134+
self?.activityIndicatorView.stopAnimating()
135+
window?.isUserInteractionEnabled = true
128136
if let blog = self?.blog {
129137
let service = BlogService(coreDataStack: ContextManager.shared)
130138
service.remove(blog)
@@ -134,7 +142,8 @@ open class JetpackConnectionViewController: UITableViewController {
134142
}
135143
},
136144
failure: { [weak self] error in
137-
self?.stopLoading()
145+
self?.activityIndicatorView.stopAnimating()
146+
window?.isUserInteractionEnabled = true
138147
let errorTitle = NSLocalizedString(
139148
"Error disconnecting Jetpack",
140149
comment: "Title of error dialog when disconnecting jetpack fails."
@@ -157,20 +166,3 @@ open class JetpackConnectionViewController: UITableViewController {
157166
}
158167
}
159168
}
160-
161-
// MARK: - Loading
162-
163-
/// Loading blocks user interactions while loading is in progress since navigating from this view controller
164-
/// during Jetpack connection or disconnection process can leave the application in an undetermined state.
165-
///
166-
private extension JetpackConnectionViewController {
167-
func startLoading() {
168-
activityIndicatorView.startAnimating()
169-
UIApplication.shared.mainWindow?.isUserInteractionEnabled = false
170-
}
171-
172-
func stopLoading() {
173-
activityIndicatorView.stopAnimating()
174-
UIApplication.shared.mainWindow?.isUserInteractionEnabled = true
175-
}
176-
}

WordPress/Classes/ViewRelated/Me/App Settings/AppSettingsViewController.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -297,7 +297,7 @@ class AppSettingsViewController: UITableViewController {
297297
}
298298

299299
private func overrideAppAppearance(with style: UIUserInterfaceStyle) {
300-
let transitionView: UIView = WordPressAppDelegate.shared?.window ?? view
300+
let transitionView: UIView = view.window ?? view
301301
UIView.transition(with: transitionView,
302302
duration: 0.3,
303303
options: .transitionCrossDissolve,

WordPress/Classes/ViewRelated/Me/App Settings/DebugMenuViewController.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -257,13 +257,13 @@ final class DebugMenuViewController: UIHostingController<DebugMenuView> {
257257

258258
assert(window != nil)
259259

260-
let gesture = UIScreenEdgePanGestureRecognizer(target: DebugMenuViewController.self, action: #selector(showDebugMenu))
260+
let gesture = UIScreenEdgePanGestureRecognizer(target: DebugMenuViewController.self, action: #selector(showDebugMenu(_:)))
261261
gesture.edges = .right
262262
window?.addGestureRecognizer(gesture)
263263
}
264264

265-
@objc private static func showDebugMenu() {
266-
guard let window = UIApplication.sharedIfAvailable()?.mainWindow,
265+
@objc private static func showDebugMenu(_ sender: UIScreenEdgePanGestureRecognizer) {
266+
guard let window = sender.view as? UIWindow,
267267
let topViewController = window.topmostPresentedViewController,
268268
!((topViewController as? UINavigationController)?.viewControllers.first is DebugMenuViewController) else {
269269
return

WordPress/Classes/ViewRelated/Notifications/Controllers/NotificationDetailsViewController.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -724,14 +724,14 @@ private extension NotificationDetailsViewController {
724724
func showConfettiIfNeeded() {
725725
guard note.isViewMilestone,
726726
!confettiWasShown,
727-
let view = UIApplication.shared.mainWindow,
727+
let window = view.window,
728728
let frame = navigationController?.view.frame else {
729729
return
730730
}
731731
// This method will remove any existing `ConfettiView` before adding a new one
732732
// This ensures that when we navigate through notifications, if there is an
733733
// ongoging animation, it will be removed and replaced by a new one
734-
ConfettiView.cleanupAndAnimate(on: view, frame: frame) { confettiView in
734+
ConfettiView.cleanupAndAnimate(on: window, frame: frame) { confettiView in
735735

736736
// removing this instance when the animation completes, will prevent
737737
// the animation to suddenly stop if users navigate away from the note

0 commit comments

Comments
 (0)