Fix a crash that could happen when laying out the progress view while it’s not in the view hierarchy. Fix #1764.

This commit is contained in:
Brent Simmons 2020-02-01 12:19:39 -08:00
parent 2f9506a8b8
commit b50fabe325

View File

@ -13,7 +13,7 @@ class RefreshProgressView: UIView {
@IBOutlet weak var progressView: UIProgressView! @IBOutlet weak var progressView: UIProgressView!
@IBOutlet weak var label: UILabel! @IBOutlet weak var label: UILabel!
private lazy var progressWidth = progressView.widthAnchor.constraint(equalToConstant: 100.0) private lazy var progressWidthConstraint = progressView.widthAnchor.constraint(equalToConstant: 100.0)
override func awakeFromNib() { override func awakeFromNib() {
NotificationCenter.default.addObserver(self, selector: #selector(progressDidChange(_:)), name: .AccountRefreshProgressDidChange, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(progressDidChange(_:)), name: .AccountRefreshProgressDidChange, object: nil)
@ -28,6 +28,10 @@ class RefreshProgressView: UIView {
scheduleUpdateRefreshLabel() scheduleUpdateRefreshLabel()
} }
override func didMoveToSuperview() {
progressChanged()
}
func updateRefreshLabel() { func updateRefreshLabel() {
if let accountLastArticleFetchEndTime = AccountManager.shared.lastArticleFetchEndTime { if let accountLastArticleFetchEndTime = AccountManager.shared.lastArticleFetchEndTime {
@ -71,23 +75,32 @@ class RefreshProgressView: UIView {
private extension RefreshProgressView { private extension RefreshProgressView {
func progressChanged() { func progressChanged() {
// Layout may crash if not in the view hierarchy.
// https://github.com/Ranchero-Software/NetNewsWire/issues/1764
let isInViewHierarchy = self.superview != nil
let progress = AccountManager.shared.combinedRefreshProgress let progress = AccountManager.shared.combinedRefreshProgress
if progress.isComplete { if progress.isComplete {
if isInViewHierarchy {
progressView.setProgress(1, animated: true) progressView.setProgress(1, animated: true)
}
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
self.updateRefreshLabel() self.updateRefreshLabel()
self.label.isHidden = false self.label.isHidden = false
self.progressView.isHidden = true self.progressView.isHidden = true
self.progressWidth.isActive = false self.progressWidthConstraint.isActive = false
if isInViewHierarchy {
self.progressView.setProgress(0, animated: true) self.progressView.setProgress(0, animated: true)
} }
}
} else { } else {
label.isHidden = true label.isHidden = true
progressView.isHidden = false progressView.isHidden = false
self.progressWidth.isActive = true progressWidthConstraint.isActive = true
self.progressView.setNeedsLayout() if isInViewHierarchy {
self.progressView.layoutIfNeeded() progressView.setNeedsLayout()
progressView.layoutIfNeeded()
let percent = Float(progress.numberCompleted) / Float(progress.numberOfTasks) let percent = Float(progress.numberCompleted) / Float(progress.numberOfTasks)
// Don't let the progress bar go backwards unless we need to go back more than 25% // Don't let the progress bar go backwards unless we need to go back more than 25%
@ -96,6 +109,7 @@ private extension RefreshProgressView {
} }
} }
} }
}
func scheduleUpdateRefreshLabel() { func scheduleUpdateRefreshLabel() {
DispatchQueue.main.asyncAfter(deadline: .now() + 60) { [weak self] in DispatchQueue.main.asyncAfter(deadline: .now() + 60) { [weak self] in