mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-22 14:20:20 +00:00
Reaction improvements
This commit is contained in:
@@ -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)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user