// // UIScrollView+Top.swift // Tusker // // Created by Shadowfacts on 11/1/22. // Copyright © 2022 Shadowfacts. All rights reserved. // import UIKit private let prevScrollOffsetBeforeScrollToTopKey = UnsafeMutableRawPointer.allocate(byteCount: 0, alignment: 0) extension UIScrollView { private var prevScrollOffsetBeforeScrollToTop: CGFloat? { get { if let v = (objc_getAssociatedObject(self, prevScrollOffsetBeforeScrollToTopKey) as? NSNumber)?.doubleValue { return CGFloat(v) } else { return nil } } set { if let newValue { objc_setAssociatedObject(self, prevScrollOffsetBeforeScrollToTopKey, NSNumber(value: newValue), .OBJC_ASSOCIATION_COPY_NONATOMIC) } else { objc_setAssociatedObject(self, prevScrollOffsetBeforeScrollToTopKey, nil, .OBJC_ASSOCIATION_COPY_NONATOMIC) } } } func scrollToTop() { let top = -adjustedContentInset.top // +5 to add a little bit of wiggle room let isScrolledToTop = contentOffset.y < top + 5 if isScrolledToTop { if let prevScrollOffsetBeforeScrollToTop { self.prevScrollOffsetBeforeScrollToTop = nil setContentOffset(CGPoint(x: 0, y: prevScrollOffsetBeforeScrollToTop), animated: true) } } else { prevScrollOffsetBeforeScrollToTop = contentOffset.y setContentOffset(CGPoint(x: 0, y: top), animated: true) } } }