Fix context menu tip layout

This commit is contained in:
Ali 2022-08-21 19:39:22 +03:00
parent 39123008e2
commit 30c018c4a2
2 changed files with 70 additions and 11 deletions

View File

@ -658,6 +658,7 @@ public final class ReactionListContextMenuContent: ContextControllerItemsContent
private let scrollNode: ASScrollNode private let scrollNode: ASScrollNode
private var ignoreScrolling: Bool = false private var ignoreScrolling: Bool = false
private var animateIn: Bool = false private var animateIn: Bool = false
private var bottomScrollInset: CGFloat = 0.0
private var presentationData: PresentationData? private var presentationData: PresentationData?
private var currentSize: CGSize? 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 let itemHeight: CGFloat = 44.0
if self.presentationData?.theme !== presentationData.theme { if self.presentationData?.theme !== presentationData.theme {
@ -895,8 +907,13 @@ public final class ReactionListContextMenuContent: ContextControllerItemsContent
if self.scrollNode.frame != CGRect(origin: CGPoint(), size: containerSize) { if self.scrollNode.frame != CGRect(origin: CGPoint(), size: containerSize) {
self.scrollNode.frame = CGRect(origin: CGPoint(), size: containerSize) self.scrollNode.frame = CGRect(origin: CGPoint(), size: containerSize)
} }
if self.scrollNode.view.contentSize != size { if self.scrollNode.view.contentInset.bottom != bottomInset {
self.scrollNode.view.contentSize = size 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 self.ignoreScrolling = false
@ -1216,7 +1233,7 @@ public final class ReactionListContextMenuContent: ContextControllerItemsContent
tabTransition = .immediate 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 tabLayouts[index] = tabLayout
let currentFractionalTabIndex: CGFloat let currentFractionalTabIndex: CGFloat
if let interactiveTransitionState = self.interactiveTransitionState { if let interactiveTransitionState = self.interactiveTransitionState {

View File

@ -14,11 +14,14 @@ import AnimationCache
import MultiAnimationRenderer import MultiAnimationRenderer
public protocol ContextControllerActionsStackItemNode: ASDisplayNode { public protocol ContextControllerActionsStackItemNode: ASDisplayNode {
var wantsFullWidth: Bool { get }
func update( func update(
presentationData: PresentationData, presentationData: PresentationData,
constrainedSize: CGSize, constrainedSize: CGSize,
standardMinWidth: CGFloat, standardMinWidth: CGFloat,
standardMaxWidth: CGFloat, standardMaxWidth: CGFloat,
additionalBottomInset: CGFloat,
transition: ContainedViewLayoutTransition transition: ContainedViewLayoutTransition
) -> (size: CGSize, apparentHeight: CGFloat) ) -> (size: CGSize, apparentHeight: CGFloat)
@ -411,6 +414,10 @@ final class ContextControllerActionsListStackItem: ContextControllerActionsStack
private var hapticFeedback: HapticFeedback? private var hapticFeedback: HapticFeedback?
private var highlightedItemNode: Item? private var highlightedItemNode: Item?
var wantsFullWidth: Bool {
return false
}
init( init(
getController: @escaping () -> ContextControllerProtocol?, getController: @escaping () -> ContextControllerProtocol?,
requestDismiss: @escaping (ContextMenuActionResult) -> Void, requestDismiss: @escaping (ContextMenuActionResult) -> Void,
@ -507,6 +514,7 @@ final class ContextControllerActionsListStackItem: ContextControllerActionsStack
constrainedSize: CGSize, constrainedSize: CGSize,
standardMinWidth: CGFloat, standardMinWidth: CGFloat,
standardMaxWidth: CGFloat, standardMaxWidth: CGFloat,
additionalBottomInset: CGFloat,
transition: ContainedViewLayoutTransition transition: ContainedViewLayoutTransition
) -> (size: CGSize, apparentHeight: CGFloat) { ) -> (size: CGSize, apparentHeight: CGFloat) {
var itemNodeLayouts: [(minSize: CGSize, apply: (_ size: CGSize, _ transition: ContainedViewLayoutTransition) -> Void)] = [] var itemNodeLayouts: [(minSize: CGSize, apply: (_ size: CGSize, _ transition: ContainedViewLayoutTransition) -> Void)] = []
@ -677,18 +685,23 @@ final class ContextControllerActionsCustomStackItem: ContextControllerActionsSta
self.addSubnode(self.contentNode) self.addSubnode(self.contentNode)
} }
var wantsFullWidth: Bool {
return true
}
func update( func update(
presentationData: PresentationData, presentationData: PresentationData,
constrainedSize: CGSize, constrainedSize: CGSize,
standardMinWidth: CGFloat, standardMinWidth: CGFloat,
standardMaxWidth: CGFloat, standardMaxWidth: CGFloat,
additionalBottomInset: CGFloat,
transition: ContainedViewLayoutTransition transition: ContainedViewLayoutTransition
) -> (size: CGSize, apparentHeight: CGFloat) { ) -> (size: CGSize, apparentHeight: CGFloat) {
let contentLayout = self.contentNode.update( let contentLayout = self.contentNode.update(
presentationData: presentationData, presentationData: presentationData,
constrainedWidth: constrainedSize.width, constrainedWidth: constrainedSize.width,
maxHeight: constrainedSize.height, maxHeight: constrainedSize.height,
bottomInset: 0.0, bottomInset: additionalBottomInset,
transition: transition transition: transition
) )
transition.updateFrame(node: self.contentNode, frame: CGRect(origin: CGPoint(), size: contentLayout.cleanSize), beginWithCurrentState: true) transition.updateFrame(node: self.contentNode, frame: CGRect(origin: CGPoint(), size: contentLayout.cleanSize), beginWithCurrentState: true)
@ -925,6 +938,7 @@ final class ContextControllerActionsStackNode: ASDisplayNode {
constrainedSize: CGSize, constrainedSize: CGSize,
standardMinWidth: CGFloat, standardMinWidth: CGFloat,
standardMaxWidth: CGFloat, standardMaxWidth: CGFloat,
additionalBottomInset: CGFloat,
transitionFraction: CGFloat, transitionFraction: CGFloat,
transition: ContainedViewLayoutTransition transition: ContainedViewLayoutTransition
) -> (size: CGSize, apparentHeight: CGFloat) { ) -> (size: CGSize, apparentHeight: CGFloat) {
@ -933,6 +947,7 @@ final class ContextControllerActionsStackNode: ASDisplayNode {
constrainedSize: constrainedSize, constrainedSize: constrainedSize,
standardMinWidth: standardMinWidth, standardMinWidth: standardMinWidth,
standardMaxWidth: standardMaxWidth, standardMaxWidth: standardMaxWidth,
additionalBottomInset: additionalBottomInset,
transition: transition transition: transition
) )
@ -1198,11 +1213,37 @@ final class ContextControllerActionsStackNode: ASDisplayNode {
alphaTransitionFraction = 0.0 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( let itemSize = itemContainer.update(
presentationData: presentationData, presentationData: presentationData,
constrainedSize: CGSize(width: constrainedSize.width, height: itemConstrainedHeight), constrainedSize: itemContainerConstrainedSize,
standardMinWidth: 220.0, standardMinWidth: standardMinWidth,
standardMaxWidth: 240.0, standardMaxWidth: standardMaxWidth,
additionalBottomInset: additionalBottomInset,
transitionFraction: alphaTransitionFraction, transitionFraction: alphaTransitionFraction,
transition: itemContainerTransition transition: itemContainerTransition
) )
@ -1210,9 +1251,10 @@ final class ContextControllerActionsStackNode: ASDisplayNode {
topItemSize = itemSize.size topItemSize = itemSize.size
} }
var tip: TipLayout? if !itemContainer.node.wantsFullWidth {
if let (tipNode, tipHeight) = itemContainer.updateTip(presentationData: presentationData, width: itemSize.size.width, transition: itemContainerTransition) { if let (tipNode, tipHeight) = itemContainer.updateTip(presentationData: presentationData, width: itemSize.size.width, transition: itemContainerTransition) {
tip = TipLayout(tipNode: tipNode, tipHeight: tipHeight) tip = TipLayout(tipNode: tipNode, tipHeight: tipHeight)
}
} }
itemLayouts.append(ItemLayout( itemLayouts.append(ItemLayout(