Skip to content

Commit e16a520

Browse files
authored
Fix a inifity loop crash by debouncing changing toolbarHidden value (#24869)
2 parents b52b801 + 252307e commit e16a520

File tree

1 file changed

+17
-3
lines changed

1 file changed

+17
-3
lines changed

WordPress/Classes/ViewRelated/Reader/Detail/ReaderDetailViewController.swift

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import AutomatticTracks
44
import WordPressReader
55
import WordPressData
66
import WordPressKit
7+
import Combine
78
@preconcurrency import WebKit
89

910
typealias RelatedPostsSection = (postType: RemoteReaderSimplePost.PostType, posts: [RemoteReaderSimplePost])
@@ -88,6 +89,8 @@ class ReaderDetailViewController: UIViewController, ReaderDetailView {
8889
private var lastContentOffset: CGFloat = 0
8990

9091
private var toolbarUpdateTimer: Timer?
92+
private let toolbarHiddenDebouncer = PassthroughSubject<Bool, Never>()
93+
private var toolbarHiddenDebounceCancellable: AnyCancellable?
9194

9295
/// Likes summary view
9396
private let likesSummary: ReaderDetailLikesView = .loadFromNib()
@@ -184,6 +187,17 @@ class ReaderDetailViewController: UIViewController, ReaderDetailView {
184187

185188
// When comments are moderated or edited from the Comments view, update the Comments snippet here.
186189
NotificationCenter.default.addObserver(self, selector: #selector(fetchComments), name: .ReaderCommentModifiedNotification, object: nil)
190+
191+
// In the `scrollViewDidScroll` function, "toolbar hidden" is toggled repeatedly when the scroll view in the
192+
// middle of scrolling animation. This debouncer is introduced to avoid toggling
193+
// `navigationController.toolbarHidden`, which causes inifity loops.
194+
// Sentry issue: https://a8c.sentry.io/issues/6884521550
195+
toolbarHiddenDebounceCancellable = toolbarHiddenDebouncer
196+
.removeDuplicates()
197+
.debounce(for: .milliseconds(100), scheduler: DispatchQueue.main)
198+
.sink { [weak self] isHidden in
199+
self?.setToolbarHidden(isHidden, animated: true)
200+
}
187201
}
188202

189203
override func viewWillAppear(_ animated: Bool) {
@@ -895,11 +909,11 @@ extension ReaderDetailViewController: UIScrollViewDelegate {
895909
// Using `safeAreaLayoutGuide.layoutFrame.height` because it doesn't
896910
// change when we extend the scroll view size by hiding the toolbar
897911
if (currentOffset + view.safeAreaLayoutGuide.layoutFrame.height) > likesContainerView.frame.minY {
898-
setToolbarHidden(false, animated: true) // Reached bottom (controls, comments, etc)
912+
toolbarHiddenDebouncer.send(false) // Reached bottom (controls, comments, etc)
899913
} else if currentOffset > lastContentOffset && currentOffset > 0 {
900-
setToolbarHidden(true, animated: true) // Scrolling down
914+
toolbarHiddenDebouncer.send(true) // Scrolling down
901915
} else if currentOffset < lastContentOffset {
902-
setToolbarHidden(false, animated: true) // Scrolling up
916+
toolbarHiddenDebouncer.send(false) // Scrolling up
903917
}
904918
lastContentOffset = currentOffset
905919
layoutHeroView()

0 commit comments

Comments
 (0)