There seems to be a regression in the behavior of UIScrollEdgeElementContainerInteraction
on iOS 26.1 when it's over a WKWebView
. If the web view's scroll view's topEdgeEffect.style
is changed to .hard
and then back to .soft
, it will stop tracking the color of the content underneath it and use the wrong-mix in color in its blur.
I've filed this as FB20655398.
Here's some sample code to illustrate the issue. The test.html
file being loaded is just a bunch of div
elements with lorem ipsum.
private var webView: WKWebView? = nil
override func viewDidLoad() {
super.viewDidLoad()
let config = WKWebViewConfiguration()
let webView = WKWebView(frame: .zero, configuration: config)
webView.navigationDelegate = self
self.view.addSubview(webView)
webView.autoPinEdgesToSuperviewEdges()
webView.isInspectable = true
self.webView = webView
let url = Bundle.main.url(forResource: "test", withExtension: "html")!
webView.loadFileURL(url, allowingReadAccessTo: Bundle.main.bundleURL)
let blurView = UIView()
self.view.addSubview(blurView)
blurView.autoPinEdgesToSuperviewEdges(with: .zero, excludingEdge: .bottom)
let label = UILabel()
label.text = "This is a title bar"
blurView.addSubview(label)
label.autoAlignAxis(toSuperviewAxis: .vertical)
label.autoPinEdge(toSuperviewEdge: .bottom, withInset: 8)
label.autoPinEdge(toSuperviewSafeArea: .top, withInset: 8)
let interaction = UIScrollEdgeElementContainerInteraction()
interaction.scrollView = webView.scrollView
interaction.edge = .top
blurView.addInteraction(interaction)
self.webView?.scrollView.topEdgeEffect.style = .hard
DispatchQueue.main.asyncAfterUnsafe(deadline: .now() + .seconds(2)) {
self.webView?.scrollView.topEdgeEffect.style = .soft
}
registerForTraitChanges([UITraitUserInterfaceStyle.self]) { (self: Self, previousTraitCollection: UITraitCollection) in
self._updateWebViewColors()
}
}
private func _updateWebViewColors() {
let dark = self.traitCollection.userInterfaceStyle == .dark
let text = dark ? "#FFFFFF" : "#000000"
let bg = dark ? "#000000" : "#FFFFFF"
let js = "document.body.style.color = '\(text)';\ndocument.body.style.backgroundColor = '\(bg)';"
self.webView?.evaluateJavaScript(js) { res, err in
if let err {
print("JS error: \(err)")
}
}
}
If you run that, then change the system them to dark mode, you get this. Has anyone else seen this before? Know how to work around it?