diff --git a/Reader/AppDelegate.swift b/Reader/AppDelegate.swift index 8355c24..218d4cb 100644 --- a/Reader/AppDelegate.swift +++ b/Reader/AppDelegate.swift @@ -115,21 +115,28 @@ class AppDelegate: UIResponder, UIApplicationDelegate { } } + // this workaround is no longer necessary (in fact, it causes a stack overflow) post-iOS 15.4 because of: + // https://github.com/WebKit/WebKit/commit/1dbd34cf01d8b5aedcb8820b13cb6553ed60e8ed + @available(iOS, obsoleted: 15.4) private func swizzleWKWebView() { - let selector = Selector(("_updateScrollViewBackground")) - var originalIMP: IMP? - let imp = imp_implementationWithBlock({ (self: WKWebView) in - if let originalIMP = originalIMP { - let original = unsafeBitCast(originalIMP, to: (@convention(c) (WKWebView, Selector) -> Void).self) - original(self, selector) - } else { + if #available(iOS 15.4, *) { + } else { + let selector = Selector(("_updateScrollViewBackground")) + var originalIMP: IMP? + let imp = imp_implementationWithBlock({ (self: WKWebView) in + if let originalIMP = originalIMP { + let original = unsafeBitCast(originalIMP, to: (@convention(c) (WKWebView, Selector) -> Void).self) + original(self, selector) + } + + self.scrollView.indicatorStyle = .default + + } as (@convention(block) (WKWebView) -> Void)) + originalIMP = class_replaceMethod(WKWebView.self, selector, imp, "v@:") + if originalIMP == nil { os_log(.error, "Missing originalIMP for -[WKWebView _updateScrollViewBackground], did WebKit change?") } - - self.scrollView.indicatorStyle = .default - - } as (@convention(block) (WKWebView) -> Void)) - originalIMP = class_replaceMethod(WKWebView.self, selector, imp, "v@:") + } } @objc private func showPreferences() { diff --git a/Reader/Screens/Read/ReadViewController.swift b/Reader/Screens/Read/ReadViewController.swift index bbebd9d..ef60f16 100644 --- a/Reader/Screens/Read/ReadViewController.swift +++ b/Reader/Screens/Read/ReadViewController.swift @@ -22,6 +22,8 @@ class ReadViewController: UIViewController { let fervorController: FervorController let item: Item + private var webView: WKWebView! + #if targetEnvironment(macCatalyst) private var itemReadObservation: NSKeyValueObservation? #endif @@ -53,7 +55,7 @@ class ReadViewController: UIViewController { view.backgroundColor = .appBackground view.addInteraction(StretchyMenuInteraction(delegate: self)) - let webView = WKWebView() + webView = WKWebView() webView.translatesAutoresizingMaskIntoConstraints = false webView.navigationDelegate = self webView.uiDelegate = self @@ -83,6 +85,36 @@ class ReadViewController: UIViewController { #endif } + override func viewWillAppear(_ animated: Bool) { + super.viewWillAppear(animated) + + updateScrollIndicatorStyle() + } + + override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) { + super.traitCollectionDidChange(previousTraitCollection) + + updateScrollIndicatorStyle() + } + + private func updateScrollIndicatorStyle() { + guard #available(iOS 15.4, *) else { + // different workaround pre-iOS 15.4 + return + } + // can't use .default because that causes the WKScrollView to think the indicator style has not been set by the client (us): + // https://github.com/WebKit/WebKit/blob/1dbd34cf01d8b5aedcb8820b13cb6553ed60e8ed/Source/WebKit/UIProcess/ios/WKScrollView.mm#L247 + // if that happens, it goes back to trying to set it based on background color which doesn't work because we give it a clear background + // https://github.com/WebKit/WebKit/blob/d085008d57f784d0913a8c37351f60b4a0eb8a3a/Source/WebKit/UIProcess/API/ios/WKWebViewIOS.mm#L562 + // https://github.com/WebKit/WebKit/blob/d085008d57f784d0913a8c37351f60b4a0eb8a3a/Source/WebKit/UIProcess/API/ios/WKWebViewIOS.mm#L520 + // so, we set it ourselves based on the user interface style + if traitCollection.userInterfaceStyle == .dark { + webView.scrollView.indicatorStyle = .white + } else { + webView.scrollView.indicatorStyle = .black + } + } + private static let css = try! String(contentsOf: Bundle.main.url(forResource: "read", withExtension: "css")!) private static let js = try! String(contentsOf: Bundle.main.url(forResource: "read", withExtension: "js")!)