From 30c018c4a299f20b51e8fdca36ca655eb6ec8eb7 Mon Sep 17 00:00:00 2001 From: Ali <> Date: Sun, 21 Aug 2022 19:39:22 +0300 Subject: [PATCH] Fix context menu tip layout --- .../ReactionListContextMenuContent.swift | 25 +++++++-- .../ContextControllerActionsStackNode.swift | 56 ++++++++++++++++--- 2 files changed, 70 insertions(+), 11 deletions(-) diff --git a/submodules/Components/ReactionListContextMenuContent/Sources/ReactionListContextMenuContent.swift b/submodules/Components/ReactionListContextMenuContent/Sources/ReactionListContextMenuContent.swift index 3ce490102c..68a7782cbc 100644 --- a/submodules/Components/ReactionListContextMenuContent/Sources/ReactionListContextMenuContent.swift +++ b/submodules/Components/ReactionListContextMenuContent/Sources/ReactionListContextMenuContent.swift @@ -658,6 +658,7 @@ public final class ReactionListContextMenuContent: ContextControllerItemsContent private let scrollNode: ASScrollNode private var ignoreScrolling: Bool = false private var animateIn: Bool = false + private var bottomScrollInset: CGFloat = 0.0 private var presentationData: PresentationData? private var currentSize: CGSize? @@ -846,7 +847,18 @@ public final class ReactionListContextMenuContent: ContextControllerItemsContent } } - func update(presentationData: PresentationData, constrainedSize: CGSize, transition: ContainedViewLayoutTransition) -> (height: CGFloat, apparentHeight: CGFloat) { + override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? { + var extendedScrollNodeFrame = self.scrollNode.frame + extendedScrollNodeFrame.size.height += self.bottomScrollInset + + if extendedScrollNodeFrame.contains(point) { + return self.scrollNode.view.hitTest(self.view.convert(point, to: self.scrollNode.view), with: event) + } + + return super.hitTest(point, with: event) + } + + func update(presentationData: PresentationData, constrainedSize: CGSize, bottomInset: CGFloat, transition: ContainedViewLayoutTransition) -> (height: CGFloat, apparentHeight: CGFloat) { let itemHeight: CGFloat = 44.0 if self.presentationData?.theme !== presentationData.theme { @@ -895,8 +907,13 @@ public final class ReactionListContextMenuContent: ContextControllerItemsContent if self.scrollNode.frame != CGRect(origin: CGPoint(), size: containerSize) { self.scrollNode.frame = CGRect(origin: CGPoint(), size: containerSize) } - if self.scrollNode.view.contentSize != size { - self.scrollNode.view.contentSize = size + if self.scrollNode.view.contentInset.bottom != bottomInset { + self.scrollNode.view.contentInset.bottom = bottomInset + } + self.bottomScrollInset = bottomInset + let scrollContentSize = CGSize(width: size.width, height: size.height) + if self.scrollNode.view.contentSize != scrollContentSize { + self.scrollNode.view.contentSize = scrollContentSize } self.ignoreScrolling = false @@ -1216,7 +1233,7 @@ public final class ReactionListContextMenuContent: ContextControllerItemsContent tabTransition = .immediate } - let tabLayout = tabNode.update(presentationData: presentationData, constrainedSize: CGSize(width: constrainedSize.width, height: constrainedSize.height - topContentHeight), transition: tabTransition) + let tabLayout = tabNode.update(presentationData: presentationData, constrainedSize: CGSize(width: constrainedSize.width, height: constrainedSize.height - topContentHeight), bottomInset: bottomInset, transition: tabTransition) tabLayouts[index] = tabLayout let currentFractionalTabIndex: CGFloat if let interactiveTransitionState = self.interactiveTransitionState { diff --git a/submodules/ContextUI/Sources/ContextControllerActionsStackNode.swift b/submodules/ContextUI/Sources/ContextControllerActionsStackNode.swift index 0f26d0e7b8..71d3887b54 100644 --- a/submodules/ContextUI/Sources/ContextControllerActionsStackNode.swift +++ b/submodules/ContextUI/Sources/ContextControllerActionsStackNode.swift @@ -14,11 +14,14 @@ import AnimationCache import MultiAnimationRenderer public protocol ContextControllerActionsStackItemNode: ASDisplayNode { + var wantsFullWidth: Bool { get } + func update( presentationData: PresentationData, constrainedSize: CGSize, standardMinWidth: CGFloat, standardMaxWidth: CGFloat, + additionalBottomInset: CGFloat, transition: ContainedViewLayoutTransition ) -> (size: CGSize, apparentHeight: CGFloat) @@ -411,6 +414,10 @@ final class ContextControllerActionsListStackItem: ContextControllerActionsStack private var hapticFeedback: HapticFeedback? private var highlightedItemNode: Item? + var wantsFullWidth: Bool { + return false + } + init( getController: @escaping () -> ContextControllerProtocol?, requestDismiss: @escaping (ContextMenuActionResult) -> Void, @@ -507,6 +514,7 @@ final class ContextControllerActionsListStackItem: ContextControllerActionsStack constrainedSize: CGSize, standardMinWidth: CGFloat, standardMaxWidth: CGFloat, + additionalBottomInset: CGFloat, transition: ContainedViewLayoutTransition ) -> (size: CGSize, apparentHeight: CGFloat) { var itemNodeLayouts: [(minSize: CGSize, apply: (_ size: CGSize, _ transition: ContainedViewLayoutTransition) -> Void)] = [] @@ -677,18 +685,23 @@ final class ContextControllerActionsCustomStackItem: ContextControllerActionsSta self.addSubnode(self.contentNode) } + var wantsFullWidth: Bool { + return true + } + func update( presentationData: PresentationData, constrainedSize: CGSize, standardMinWidth: CGFloat, standardMaxWidth: CGFloat, + additionalBottomInset: CGFloat, transition: ContainedViewLayoutTransition ) -> (size: CGSize, apparentHeight: CGFloat) { let contentLayout = self.contentNode.update( presentationData: presentationData, constrainedWidth: constrainedSize.width, maxHeight: constrainedSize.height, - bottomInset: 0.0, + bottomInset: additionalBottomInset, transition: transition ) transition.updateFrame(node: self.contentNode, frame: CGRect(origin: CGPoint(), size: contentLayout.cleanSize), beginWithCurrentState: true) @@ -925,6 +938,7 @@ final class ContextControllerActionsStackNode: ASDisplayNode { constrainedSize: CGSize, standardMinWidth: CGFloat, standardMaxWidth: CGFloat, + additionalBottomInset: CGFloat, transitionFraction: CGFloat, transition: ContainedViewLayoutTransition ) -> (size: CGSize, apparentHeight: CGFloat) { @@ -933,6 +947,7 @@ final class ContextControllerActionsStackNode: ASDisplayNode { constrainedSize: constrainedSize, standardMinWidth: standardMinWidth, standardMaxWidth: standardMaxWidth, + additionalBottomInset: additionalBottomInset, transition: transition ) @@ -1198,11 +1213,37 @@ final class ContextControllerActionsStackNode: ASDisplayNode { alphaTransitionFraction = 0.0 } + var tip: TipLayout? + + let itemContainerConstrainedSize: CGSize + let standardMinWidth: CGFloat + let standardMaxWidth: CGFloat + let additionalBottomInset: CGFloat + + if itemContainer.node.wantsFullWidth { + itemContainerConstrainedSize = CGSize(width: constrainedSize.width, height: itemConstrainedHeight) + standardMaxWidth = 240.0 + standardMinWidth = standardMaxWidth + + if let (tipNode, tipHeight) = itemContainer.updateTip(presentationData: presentationData, width: standardMaxWidth, transition: itemContainerTransition) { + tip = TipLayout(tipNode: tipNode, tipHeight: tipHeight) + additionalBottomInset = tipHeight + 10.0 + } else { + additionalBottomInset = 0.0 + } + } else { + itemContainerConstrainedSize = CGSize(width: constrainedSize.width, height: itemConstrainedHeight) + standardMinWidth = 220.0 + standardMaxWidth = 240.0 + additionalBottomInset = 0.0 + } + let itemSize = itemContainer.update( presentationData: presentationData, - constrainedSize: CGSize(width: constrainedSize.width, height: itemConstrainedHeight), - standardMinWidth: 220.0, - standardMaxWidth: 240.0, + constrainedSize: itemContainerConstrainedSize, + standardMinWidth: standardMinWidth, + standardMaxWidth: standardMaxWidth, + additionalBottomInset: additionalBottomInset, transitionFraction: alphaTransitionFraction, transition: itemContainerTransition ) @@ -1210,9 +1251,10 @@ final class ContextControllerActionsStackNode: ASDisplayNode { topItemSize = itemSize.size } - var tip: TipLayout? - if let (tipNode, tipHeight) = itemContainer.updateTip(presentationData: presentationData, width: itemSize.size.width, transition: itemContainerTransition) { - tip = TipLayout(tipNode: tipNode, tipHeight: tipHeight) + if !itemContainer.node.wantsFullWidth { + if let (tipNode, tipHeight) = itemContainer.updateTip(presentationData: presentationData, width: itemSize.size.width, transition: itemContainerTransition) { + tip = TipLayout(tipNode: tipNode, tipHeight: tipHeight) + } } itemLayouts.append(ItemLayout(