From 45220c5dd34d7eb4239827489642a362fccfd842 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mariusz=20=C5=9Apiewak?= Date: Wed, 7 Aug 2024 16:42:57 +0200 Subject: [PATCH] Animate transition between New Tab Page and tab switcher (#3196) Task/Issue URL: https://app.asana.com/0/72649045549333/1207977496450583/f Tech Design URL: CC: **Description**: Adopts tab switcher transition to New Tab Page. I took a chance to clean up the old "centered search" feature, which made the adoption a bit easier. **Steps to test this PR**: 1. Check transitions of Home screen to/from tab switcher with and without favorites 2. Enable New Tab Page sections in Debug menu 3. Check transitions of New Tab Page to/from tab switcher with sections visible and turned off (Dax logo visible) 4. Create new tab from switcher. The NTP should scale up and fade in. --- .../Home.imageset/Contents.json | 13 +- DuckDuckGo/Base.lproj/Home.storyboard | 125 +----------------- DuckDuckGo/HomeScreenTransition.swift | 36 ++--- DuckDuckGo/HomeViewController.swift | 16 ++- DuckDuckGo/MainViewController.swift | 13 +- ...igationSearchHomeViewSectionRenderer.swift | 1 - DuckDuckGo/NewTabPageDaxLogoView.swift | 5 +- DuckDuckGo/NewTabPageViewController.swift | 10 ++ 8 files changed, 59 insertions(+), 160 deletions(-) diff --git a/DuckDuckGo/Assets.xcassets/Home.imageset/Contents.json b/DuckDuckGo/Assets.xcassets/Home.imageset/Contents.json index d6759226ae..acdff8855e 100644 --- a/DuckDuckGo/Assets.xcassets/Home.imageset/Contents.json +++ b/DuckDuckGo/Assets.xcassets/Home.imageset/Contents.json @@ -1,12 +1,15 @@ { "images" : [ { - "idiom" : "universal", - "filename" : "home.pdf" + "filename" : "home.pdf", + "idiom" : "universal" } ], "info" : { - "version" : 1, - "author" : "xcode" + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "preserves-vector-representation" : true } -} \ No newline at end of file +} diff --git a/DuckDuckGo/Base.lproj/Home.storyboard b/DuckDuckGo/Base.lproj/Home.storyboard index d981a937f5..0ac1f1d65c 100644 --- a/DuckDuckGo/Base.lproj/Home.storyboard +++ b/DuckDuckGo/Base.lproj/Home.storyboard @@ -1,11 +1,10 @@ - + - + - @@ -35,107 +34,13 @@ - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -154,18 +59,6 @@ - - - - - - - - - - diff --git a/DuckDuckGo/HomeScreenTransition.swift b/DuckDuckGo/HomeScreenTransition.swift index 8cc3c9f664..8de6d19b3d 100644 --- a/DuckDuckGo/HomeScreenTransition.swift +++ b/DuckDuckGo/HomeScreenTransition.swift @@ -19,6 +19,11 @@ import Core +protocol HomeScreenTransitionSource: AnyObject { + var snapshotView: UIView { get } + var rootContainerView: UIView { get } +} + class HomeScreenTransition: TabSwitcherTransition { fileprivate var homeScreenSnapshot: UIView? @@ -26,19 +31,11 @@ class HomeScreenTransition: TabSwitcherTransition { fileprivate let tabSwitcherSettings: TabSwitcherSettings = DefaultTabSwitcherSettings() - fileprivate func prepareSnapshots(with homeScreen: HomeViewController, + fileprivate func prepareSnapshots(with transitionSource: HomeScreenTransitionSource, transitionContext: UIViewControllerContextTransitioning) { - let viewToSnapshot: UIView - let frameToSnapshot: CGRect - if let logoContainer = homeScreen.logoContainer, !logoContainer.isHidden { - viewToSnapshot = logoContainer - frameToSnapshot = homeScreen.collectionView.convert(homeScreen.collectionView.bounds, - to: nil) - } else { - viewToSnapshot = homeScreen.collectionView - frameToSnapshot = viewToSnapshot.bounds - } - + let viewToSnapshot = transitionSource.snapshotView + let frameToSnapshot = transitionSource.rootContainerView.convert(transitionSource.rootContainerView.bounds, to: viewToSnapshot) + if let snapshot = viewToSnapshot.resizableSnapshotView(from: frameToSnapshot, afterScreenUpdates: false, withCapInsets: .zero) { @@ -46,13 +43,6 @@ class HomeScreenTransition: TabSwitcherTransition { snapshot.frame = imageContainer.bounds homeScreenSnapshot = snapshot } - - // This fixes animation glitch in centered search mode. - settingsButtonSnapshot = homeScreen.settingsButton.snapshotView(afterScreenUpdates: true) - if let settingsButton = settingsButtonSnapshot { - settingsButton.frame = homeScreen.view.convert(homeScreen.settingsButton.frame, to: nil) - transitionContext.containerView.addSubview(settingsButton) - } } fileprivate func tabSwitcherCellFrame(for attributes: UICollectionViewLayoutAttributes) -> CGRect { @@ -100,7 +90,7 @@ class FromHomeScreenTransition: HomeScreenTransition { tabSwitcherViewController.view.frame = transitionContext.finalFrame(for: tabSwitcherViewController) tabSwitcherViewController.prepareForPresentation() - guard let homeScreen = mainViewController.homeViewController, + guard let homeScreen = mainViewController.homeController, let tab = mainViewController.tabManager.model.currentTab, let rowIndex = tabSwitcherViewController.tabsModel.indexOf(tab: tab), let layoutAttr = tabSwitcherViewController.collectionView.layoutAttributesForItem(at: IndexPath(row: rowIndex, section: 0)) @@ -112,7 +102,7 @@ class FromHomeScreenTransition: HomeScreenTransition { let theme = ThemeManager.shared.currentTheme - solidBackground.frame = homeScreen.view.convert(homeScreen.collectionView.frame, to: nil) + solidBackground.frame = homeScreen.view.convert(homeScreen.rootContainerView.frame, to: nil) solidBackground.backgroundColor = theme.backgroundColor imageContainer.frame = solidBackground.frame @@ -173,7 +163,7 @@ class ToHomeScreenTransition: HomeScreenTransition { prepareSubviews(using: transitionContext) guard let mainViewController = transitionContext.viewController(forKey: .to) as? MainViewController, - let homeScreen = mainViewController.homeViewController, + let homeScreen = mainViewController.homeController, let tab = mainViewController.tabManager.model.currentTab, let rowIndex = tabSwitcherViewController.tabsModel.indexOf(tab: tab), let layoutAttr = tabSwitcherViewController.collectionView.layoutAttributesForItem(at: IndexPath(row: rowIndex, section: 0)) @@ -206,7 +196,7 @@ class ToHomeScreenTransition: HomeScreenTransition { UIView.animateKeyframes(withDuration: TabSwitcherTransition.Constants.duration, delay: 0, options: .calculationModeLinear, animations: { UIView.addKeyframe(withRelativeStartTime: 0, relativeDuration: 1.0) { - self.imageContainer.frame = homeScreen.view.convert(homeScreen.collectionView.frame, to: nil) + self.imageContainer.frame = homeScreen.view.convert(homeScreen.rootContainerView.frame, to: nil) self.imageContainer.layer.cornerRadius = 0 self.imageContainer.backgroundColor = theme.backgroundColor self.imageView.frame = CGRect(origin: .zero, diff --git a/DuckDuckGo/HomeViewController.swift b/DuckDuckGo/HomeViewController.swift index a65c20507e..41cb06953a 100644 --- a/DuckDuckGo/HomeViewController.swift +++ b/DuckDuckGo/HomeViewController.swift @@ -34,7 +34,6 @@ class HomeViewController: UIViewController, NewTabPage { @IBOutlet weak var ctaContainer: UIView! @IBOutlet weak var collectionView: HomeCollectionView! - @IBOutlet weak var settingsButton: UIButton! @IBOutlet weak var daxDialogContainer: UIView! @IBOutlet weak var daxDialogContainerHeight: NSLayoutConstraint! @@ -149,7 +148,6 @@ class HomeViewController: UIViewController, NewTabPage { collectionView.homePageConfiguration = homePageConfiguration configureCollectionView() - decorate() NotificationCenter.default.addObserver(self, selector: #selector(remoteMessagesDidChange), @@ -366,10 +364,16 @@ extension HomeViewController: HomeMessageViewSectionRendererDelegate { } } -extension HomeViewController { +extension HomeViewController: HomeScreenTransitionSource { + var snapshotView: UIView { + if let logoContainer = logoContainer, !logoContainer.isHidden { + return logoContainer + } else { + return collectionView + } + } - private func decorate() { - let theme = ThemeManager.shared.currentTheme - settingsButton.tintColor = theme.barTintColor + var rootContainerView: UIView { + collectionView } } diff --git a/DuckDuckGo/MainViewController.swift b/DuckDuckGo/MainViewController.swift index 51192e1955..4dc2268ffe 100644 --- a/DuckDuckGo/MainViewController.swift +++ b/DuckDuckGo/MainViewController.swift @@ -78,7 +78,7 @@ class MainViewController: UIViewController { var homeViewController: HomeViewController? var newTabPageViewController: NewTabPageViewController? - var homeController: NewTabPage? { + var homeController: (NewTabPage & HomeScreenTransitionSource)? { homeViewController ?? newTabPageViewController } var tabsBarController: TabsBarViewController? @@ -2390,7 +2390,16 @@ extension MainViewController: TabSwitcherDelegate { func tabSwitcherDidRequestNewTab(tabSwitcher: TabSwitcherViewController) { newTab() - animateLogoAppearance() + if homeViewController != nil { + animateLogoAppearance() + } else if newTabPageViewController != nil { + newTabPageViewController?.view.transform = CGAffineTransform().scaledBy(x: 0.5, y: 0.5) + newTabPageViewController?.view.alpha = 0.0 + UIView.animate(withDuration: 0.2, delay: 0.1, options: [.curveEaseInOut, .beginFromCurrentState]) { + self.newTabPageViewController?.view.transform = .identity + self.newTabPageViewController?.view.alpha = 1.0 + } + } } func tabSwitcher(_ tabSwitcher: TabSwitcherViewController, didSelectTab tab: Tab) { diff --git a/DuckDuckGo/NavigationSearchHomeViewSectionRenderer.swift b/DuckDuckGo/NavigationSearchHomeViewSectionRenderer.swift index d55c41e0ce..02c8f9023b 100644 --- a/DuckDuckGo/NavigationSearchHomeViewSectionRenderer.swift +++ b/DuckDuckGo/NavigationSearchHomeViewSectionRenderer.swift @@ -38,7 +38,6 @@ class NavigationSearchHomeViewSectionRenderer: HomeViewSectionRenderer { controller.disableContentUnderflow() controller.chromeDelegate?.setNavigationBarHidden(false) controller.collectionView.isScrollEnabled = !fixed - controller.settingsButton.isHidden = true if !fixed { controller.hideLogo() diff --git a/DuckDuckGo/NewTabPageDaxLogoView.swift b/DuckDuckGo/NewTabPageDaxLogoView.swift index 42aa6ee291..4d6e1e477c 100644 --- a/DuckDuckGo/NewTabPageDaxLogoView.swift +++ b/DuckDuckGo/NewTabPageDaxLogoView.swift @@ -21,8 +21,11 @@ import SwiftUI struct NewTabPageDaxLogoView: View { var body: some View { - VStack { + VStack(spacing: 12) { Image(.home) + .resizable() + .aspectRatio(1, contentMode: .fit) + .frame(width: 96) Image(.textDuckDuckGo) } } diff --git a/DuckDuckGo/NewTabPageViewController.swift b/DuckDuckGo/NewTabPageViewController.swift index 772ebf2faa..71f0ac7af7 100644 --- a/DuckDuckGo/NewTabPageViewController.swift +++ b/DuckDuckGo/NewTabPageViewController.swift @@ -164,3 +164,13 @@ final class NewTabPageViewController: UIHostingController