Reaction improvements

This commit is contained in:
Ali
2022-08-22 02:20:05 +03:00
parent 94dc335d04
commit e450862adf
24 changed files with 264 additions and 95 deletions

View File

@@ -179,7 +179,8 @@ final class ContextControllerExtractedPresentationNode: ASDisplayNode, ContextCo
private let dismissTapNode: ASDisplayNode
private let dismissAccessibilityArea: AccessibilityAreaNode
private let clippingNode: ASDisplayNode
private let scrollNode: ASScrollNode
private let scroller: UIScrollView
private let scrollNode: ASDisplayNode
private var reactionContextNode: ReactionContextNode?
private var reactionContextNodeIsAnimatingOut: Bool = false
@@ -192,6 +193,14 @@ final class ContextControllerExtractedPresentationNode: ASDisplayNode, ContextCo
private var strings: PresentationStrings?
private enum OverscrollMode {
case unrestricted
case topOnly
case disabled
}
private var overscrollMode: OverscrollMode = .unrestricted
init(
getController: @escaping () -> ContextControllerProtocol?,
requestUpdate: @escaping (ContainedViewLayoutTransition) -> Void,
@@ -215,13 +224,17 @@ final class ContextControllerExtractedPresentationNode: ASDisplayNode, ContextCo
self.clippingNode = ASDisplayNode()
self.clippingNode.clipsToBounds = true
self.scrollNode = ASScrollNode()
self.scrollNode.canCancelAllTouchesInViews = true
self.scrollNode.view.delaysContentTouches = false
self.scrollNode.view.showsVerticalScrollIndicator = false
self.scroller = UIScrollView()
self.scroller.canCancelContentTouches = true
self.scroller.delaysContentTouches = false
self.scroller.showsVerticalScrollIndicator = false
if #available(iOS 11.0, *) {
self.scrollNode.view.contentInsetAdjustmentBehavior = .never
self.scroller.contentInsetAdjustmentBehavior = .never
}
self.scroller.alwaysBounceVertical = true
self.scrollNode = ASDisplayNode()
self.scrollNode.view.addGestureRecognizer(self.scroller.panGestureRecognizer)
self.contentRectDebugNode = ASDisplayNode()
self.contentRectDebugNode.isUserInteractionEnabled = false
@@ -244,11 +257,7 @@ final class ContextControllerExtractedPresentationNode: ASDisplayNode, ContextCo
self.scrollNode.addSubnode(self.dismissAccessibilityArea)
self.scrollNode.addSubnode(self.actionsStackNode)
/*#if DEBUG
self.scrollNode.addSubnode(self.contentRectDebugNode)
#endif*/
self.scrollNode.view.delegate = self
self.scroller.delegate = self
self.dismissTapNode.view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(self.dismissTapGesture(_:))))
@@ -292,10 +301,65 @@ final class ContextControllerExtractedPresentationNode: ASDisplayNode, ContextCo
}
}
func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
if let reactionContextNode = self.reactionContextNode, (reactionContextNode.isExpanded || !reactionContextNode.canBeExpanded) {
self.overscrollMode = .disabled
self.scroller.alwaysBounceVertical = false
} else {
if scrollView.contentSize.height > scrollView.bounds.height {
self.overscrollMode = .unrestricted
self.scroller.alwaysBounceVertical = true
} else {
if self.reactionContextNode != nil {
self.overscrollMode = .topOnly
self.scroller.alwaysBounceVertical = true
} else {
self.overscrollMode = .disabled
self.scroller.alwaysBounceVertical = false
}
}
}
}
func scrollViewDidScroll(_ scrollView: UIScrollView) {
var adjustedBounds = scrollView.bounds
var topOverscroll: CGFloat = 0.0
switch self.overscrollMode {
case .unrestricted:
if adjustedBounds.origin.y < 0.0 {
topOverscroll = -adjustedBounds.origin.y
}
case .disabled:
break
case .topOnly:
if scrollView.contentSize.height <= scrollView.bounds.height {
if adjustedBounds.origin.y > 0.0 {
adjustedBounds.origin.y = 0.0
} else {
topOverscroll = -adjustedBounds.origin.y
}
} else {
if adjustedBounds.origin.y < 0.0 {
topOverscroll = -adjustedBounds.origin.y
} else if adjustedBounds.origin.y + adjustedBounds.height > scrollView.contentSize.height {
adjustedBounds.origin.y = scrollView.contentSize.height - adjustedBounds.height
}
}
}
self.scrollNode.bounds = adjustedBounds
if let reactionContextNode = self.reactionContextNode {
let isIntersectingContent = scrollView.contentOffset.y >= 10.0
let isIntersectingContent = adjustedBounds.minY >= 10.0
reactionContextNode.updateIsIntersectingContent(isIntersectingContent: isIntersectingContent, transition: .animated(duration: 0.25, curve: .easeInOut))
if !reactionContextNode.isExpanded && reactionContextNode.canBeExpanded {
if topOverscroll > 60.0 && self.scroller.isDragging {
self.scroller.panGestureRecognizer.state = .cancelled
reactionContextNode.expand()
} else {
reactionContextNode.updateExtension(distance: topOverscroll)
}
}
}
}
@@ -341,7 +405,7 @@ final class ContextControllerExtractedPresentationNode: ASDisplayNode, ContextCo
}
private func getCurrentScrollingState() -> CGFloat {
return self.scrollNode.view.contentOffset.y
return self.scrollNode.bounds.minY
}
private func getActionsStackPositionLock() -> CGFloat? {
@@ -410,6 +474,7 @@ final class ContextControllerExtractedPresentationNode: ASDisplayNode, ContextCo
transition.updateFrame(node: self.clippingNode, frame: CGRect(origin: CGPoint(), size: layout.size), beginWithCurrentState: true)
if self.scrollNode.frame != CGRect(origin: CGPoint(), size: layout.size) {
transition.updateFrame(node: self.scrollNode, frame: CGRect(origin: CGPoint(), size: layout.size), beginWithCurrentState: true)
transition.updateFrame(view: self.scroller, frame: CGRect(origin: CGPoint(), size: layout.size), beginWithCurrentState: true)
}
if let current = self.contentNode {
@@ -684,16 +749,16 @@ final class ContextControllerExtractedPresentationNode: ASDisplayNode, ContextCo
}
let contentSize = CGSize(width: layout.size.width, height: contentHeight)
if self.scrollNode.view.contentSize != contentSize {
let previousContentOffset = self.scrollNode.view.contentOffset
self.scrollNode.view.contentSize = contentSize
if self.scroller.contentSize != contentSize {
let previousContentOffset = self.scroller.contentOffset
self.scroller.contentSize = contentSize
if let storedScrollingState = self.actionsStackNode.storedScrollingState {
self.actionsStackNode.clearStoredScrollingState()
self.scrollNode.view.contentOffset = CGPoint(x: 0.0, y: storedScrollingState)
self.scroller.contentOffset = CGPoint(x: 0.0, y: storedScrollingState)
}
if case .none = stateTransition, transition.isAnimated {
let contentOffset = self.scrollNode.view.contentOffset
let contentOffset = self.scroller.contentOffset
transition.animateOffsetAdditive(layer: self.scrollNode.layer, offset: previousContentOffset.y - contentOffset.y)
}
}
@@ -718,7 +783,7 @@ final class ContextControllerExtractedPresentationNode: ASDisplayNode, ContextCo
let duration: Double = 0.42
let springDamping: CGFloat = 104.0
self.scrollNode.view.contentOffset = CGPoint(x: 0.0, y: defaultScrollY)
self.scroller.contentOffset = CGPoint(x: 0.0, y: defaultScrollY)
self.backgroundNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2)