From e4064976ebdda44c5a679987bc4d94280bc6075e Mon Sep 17 00:00:00 2001 From: Ilya Laktyushin Date: Mon, 28 Sep 2020 21:44:32 +0400 Subject: [PATCH] Fix search tabs appearance animation --- .../Sources/ChatListController.swift | 42 ++++++++++++++++--- .../ChatListFilterTabContainerNode.swift | 9 ++-- .../ChatListSearchFiltersContainerNode.swift | 11 ++--- submodules/Display/Source/NavigationBar.swift | 2 +- 4 files changed, 48 insertions(+), 16 deletions(-) diff --git a/submodules/ChatListUI/Sources/ChatListController.swift b/submodules/ChatListUI/Sources/ChatListController.swift index 176fdea413..4181c86f4c 100644 --- a/submodules/ChatListUI/Sources/ChatListController.swift +++ b/submodules/ChatListUI/Sources/ChatListController.swift @@ -1687,6 +1687,13 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController, scrollToTop() } + let tabsIsEmpty: Bool + if let (resolvedItems, displayTabsAtBottom) = strongSelf.tabContainerData { + tabsIsEmpty = resolvedItems.count <= 1 || displayTabsAtBottom + } else { + tabsIsEmpty = true + } + var displaySearchFilters = true if chatListView.0.entries.count < 10 { displaySearchFilters = false @@ -1701,7 +1708,16 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController, parentController.navigationBar?.setSecondaryContentNode(filterContainerNode, animated: true) } } + activate() + + if !tabsIsEmpty { + Queue.mainQueue().after(0.01) { + filterContainerNode.layer.animatePosition(from: CGPoint(x: 0.0, y: 38.0), to: CGPoint(), duration: 0.4, timingFunction: kCAMediaTimingFunctionSpring, additive: true) + + strongSelf.tabContainerNode.layer.animatePosition(from: CGPoint(), to: CGPoint(x: 0.0, y: -64.0), duration: 0.4, timingFunction: kCAMediaTimingFunctionSpring, additive: true) + } + } } } @@ -1716,20 +1732,26 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController, public func deactivateSearch(animated: Bool) { if !self.displayNavigationBar { var completion: (() -> Void)? + + var filterContainerNode: ASDisplayNode? + if animated, let searchContentNode = self.chatListDisplayNode.searchDisplayController?.contentNode as? ChatListSearchContainerNode { + filterContainerNode = searchContentNode.filterContainerNode + } + if let searchContentNode = self.searchContentNode { completion = self.chatListDisplayNode.deactivateSearch(placeholderNode: searchContentNode.placeholderNode, animated: animated) } - let filtersIsEmpty: Bool - if let (resolvedItems, displayTabsAtBottom) = tabContainerData { - filtersIsEmpty = resolvedItems.count <= 1 || displayTabsAtBottom + let tabsIsEmpty: Bool + if let (resolvedItems, displayTabsAtBottom) = self.tabContainerData { + tabsIsEmpty = resolvedItems.count <= 1 || displayTabsAtBottom } else { - filtersIsEmpty = true + tabsIsEmpty = true } - self.navigationBar?.setSecondaryContentNode(filtersIsEmpty ? nil : self.tabContainerNode, animated: false) + self.navigationBar?.setSecondaryContentNode(tabsIsEmpty ? nil : self.tabContainerNode, animated: false) if let parentController = self.parent as? TabBarController { - parentController.navigationBar?.setSecondaryContentNode(filtersIsEmpty ? nil : self.tabContainerNode, animated: animated) + parentController.navigationBar?.setSecondaryContentNode(tabsIsEmpty ? nil : self.tabContainerNode, animated: animated) } let transition: ContainedViewLayoutTransition = animated ? .animated(duration: 0.4, curve: .spring) : .immediate @@ -1738,6 +1760,14 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController, completion?() (self.parent as? TabBarController)?.updateIsTabBarHidden(false, transition: .animated(duration: 0.4, curve: .spring)) + + if let filterContainerNode = filterContainerNode { + filterContainerNode.layer.animatePosition(from: CGPoint(), to: CGPoint(x: 0.0, y: -44.0), duration: 0.4, timingFunction: kCAMediaTimingFunctionSpring, removeOnCompletion: false, additive: true) + + if !tabsIsEmpty { + self.tabContainerNode.layer.animatePosition(from: CGPoint(x: 0.0, y: -64.0), to: CGPoint(), duration: 0.4, timingFunction: kCAMediaTimingFunctionSpring, additive: true) + } + } } } diff --git a/submodules/ChatListUI/Sources/ChatListFilterTabContainerNode.swift b/submodules/ChatListUI/Sources/ChatListFilterTabContainerNode.swift index 64d5c04380..0606a777f8 100644 --- a/submodules/ChatListUI/Sources/ChatListFilterTabContainerNode.swift +++ b/submodules/ChatListUI/Sources/ChatListFilterTabContainerNode.swift @@ -625,11 +625,12 @@ final class ChatListFilterTabContainerNode: ASDisplayNode { let previousContentWidth = self.scrollNode.view.contentSize.width if self.currentParams?.presentationData.theme !== presentationData.theme { - self.selectedLineNode.image = generateImage(CGSize(width: 8.0, height: 4.0), rotatedContext: { size, context in + self.selectedLineNode.image = generateImage(CGSize(width: 5.0, height: 3.0), rotatedContext: { size, context in context.clear(CGRect(origin: CGPoint(), size: size)) context.setFillColor(presentationData.theme.list.itemAccentColor.cgColor) - context.fillEllipse(in: CGRect(origin: CGPoint(), size: CGSize(width: size.width, height: size.width))) - })?.stretchableImage(withLeftCapWidth: 4, topCapHeight: 1) + context.fillEllipse(in: CGRect(origin: CGPoint(), size: CGSize(width: size.width, height: size.height + 1.0))) + context.fill(CGRect(x: 0.0, y: 2.0, width: size.width, height: 2.0)) + })?.stretchableImage(withLeftCapWidth: 2, topCapHeight: 2) } if isReordering { @@ -859,7 +860,7 @@ final class ChatListFilterTabContainerNode: ASDisplayNode { if let selectedFrame = selectedFrame { let wasAdded = self.selectedLineNode.isHidden self.selectedLineNode.isHidden = false - let lineFrame = CGRect(origin: CGPoint(x: selectedFrame.minX, y: size.height - 4.0), size: CGSize(width: selectedFrame.width, height: 4.0)) + let lineFrame = CGRect(origin: CGPoint(x: selectedFrame.minX, y: size.height - 3.0), size: CGSize(width: selectedFrame.width, height: 3.0)) if wasAdded { self.selectedLineNode.frame = lineFrame self.selectedLineNode.alpha = 0.0 diff --git a/submodules/ChatListUI/Sources/ChatListSearchFiltersContainerNode.swift b/submodules/ChatListUI/Sources/ChatListSearchFiltersContainerNode.swift index 95dbe65460..4d18b61028 100644 --- a/submodules/ChatListUI/Sources/ChatListSearchFiltersContainerNode.swift +++ b/submodules/ChatListUI/Sources/ChatListSearchFiltersContainerNode.swift @@ -243,11 +243,12 @@ final class ChatListSearchFiltersContainerNode: ASDisplayNode { if self.currentParams?.presentationData.theme !== presentationData.theme { self.backgroundColor = presentationData.theme.rootController.navigationBar.backgroundColor - self.selectedLineNode.image = generateImage(CGSize(width: 8.0, height: 4.0), rotatedContext: { size, context in + self.selectedLineNode.image = generateImage(CGSize(width: 5.0, height: 3.0), rotatedContext: { size, context in context.clear(CGRect(origin: CGPoint(), size: size)) context.setFillColor(presentationData.theme.list.itemAccentColor.cgColor) - context.fillEllipse(in: CGRect(origin: CGPoint(), size: CGSize(width: size.width, height: size.width))) - })?.stretchableImage(withLeftCapWidth: 4, topCapHeight: 1) + context.fillEllipse(in: CGRect(origin: CGPoint(), size: CGSize(width: size.width, height: size.height + 1.0))) + context.fill(CGRect(x: 0.0, y: 2.0, width: size.width, height: 2.0)) + })?.stretchableImage(withLeftCapWidth: 2, topCapHeight: 2) } self.currentParams = (size: size, sideInset: sideInset, filters: filters, selectedFilter: selectedFilter, transitionFraction: transitionFraction, presentationData: presentationData) @@ -346,7 +347,7 @@ final class ChatListSearchFiltersContainerNode: ASDisplayNode { spacing = (size.width - titlesWidth - resolvedSideInset * 2.0) / CGFloat(tabSizes.count - 1) } - let verticalOffset: CGFloat = -3.0 + let verticalOffset: CGFloat = -4.0 for i in 0 ..< tabSizes.count { let (_, paneNodeSize, paneNode, wasAdded) = tabSizes[i] let itemNodeTransition = transition @@ -407,7 +408,7 @@ final class ChatListSearchFiltersContainerNode: ASDisplayNode { if let selectedFrame = selectedFrame { let wasAdded = self.selectedLineNode.alpha < 1.0 - let lineFrame = CGRect(origin: CGPoint(x: selectedFrame.minX, y: size.height - 4.0), size: CGSize(width: selectedFrame.width, height: 4.0)) + let lineFrame = CGRect(origin: CGPoint(x: selectedFrame.minX, y: size.height - 3.0), size: CGSize(width: selectedFrame.width, height: 3.0)) if wasAdded { self.selectedLineNode.frame = lineFrame self.selectedLineNode.alpha = 0.0 diff --git a/submodules/Display/Source/NavigationBar.swift b/submodules/Display/Source/NavigationBar.swift index 86882093e0..8cee266195 100644 --- a/submodules/Display/Source/NavigationBar.swift +++ b/submodules/Display/Source/NavigationBar.swift @@ -1215,7 +1215,7 @@ open class NavigationBar: ASDisplayNode { if self.secondaryContentNode !== secondaryContentNode { if let previous = self.secondaryContentNode, previous.supernode === self.clippingNode { if animated { - previous.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.3, removeOnCompletion: false, completion: { [weak previous] finished in + previous.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.2, removeOnCompletion: false, completion: { [weak previous] finished in if finished { previous?.removeFromSupernode() previous?.layer.removeAllAnimations()