diff --git a/podcasts/Main/MainTabBarController.swift b/podcasts/Main/MainTabBarController.swift index 8af1fd3bb3..c56ff0e16c 100644 --- a/podcasts/Main/MainTabBarController.swift +++ b/podcasts/Main/MainTabBarController.swift @@ -320,7 +320,7 @@ class MainTabBarController: UITabBarController, NavigationProtocol { } } - func navigateToFolder(_ folder: Folder, popToRootViewController: Bool = true) { + func navigateToFolder(_ folder: Folder, popToRootViewController: Bool = true, fromSourceView sourceView: UIView? = nil) { guard let navController = selectedViewController as? UINavigationController else { return } if popToRootViewController { @@ -328,6 +328,7 @@ class MainTabBarController: UITabBarController, NavigationProtocol { } let folderController = FolderViewController(folder: folder) + applyZoomTransitionIfNeeded(to: folderController, sourceView: sourceView) navController.pushViewController(folderController, animated: true) } @@ -343,7 +344,7 @@ class MainTabBarController: UITabBarController, NavigationProtocol { podcastListController.showSuggestedFolders() } - func navigateToPodcast(_ podcast: Podcast) { + func navigateToPodcast(_ podcast: Podcast, fromSourceView sourceView: UIView? = nil) { appDelegate()?.miniPlayer()?.closeUpNextAndFullPlayer(completion: { [weak self] in guard let strongSelf = self else { return } @@ -358,11 +359,21 @@ class MainTabBarController: UITabBarController, NavigationProtocol { } let podcastController = PodcastViewController(podcast: podcast) + strongSelf.applyZoomTransitionIfNeeded(to: podcastController, sourceView: sourceView) navController.pushViewController(podcastController, animated: true) } }) } + private func applyZoomTransitionIfNeeded(to viewController: UIViewController, sourceView: UIView?) { + guard let sourceView else { return } + if #available(iOS 18.0, *) { + viewController.preferredTransition = .zoom { [weak sourceView] _ in + sourceView + } + } + } + func navigateToPodcastInfo(_ podcastInfo: PodcastInfo) { appDelegate()?.miniPlayer()?.closeUpNextAndFullPlayer(completion: { [weak self] in guard let navController = self?.selectedViewController as? UINavigationController else { diff --git a/podcasts/Main/NavigationManager.swift b/podcasts/Main/NavigationManager.swift index 75a5c0d6aa..089a01cbec 100644 --- a/podcasts/Main/NavigationManager.swift +++ b/podcasts/Main/NavigationManager.swift @@ -10,6 +10,7 @@ class NavigationManager { static let folderPageKey = "folderPage" static let folderKey = "folder" static let popToRootViewController = "popToRootViewController" + static let sourceViewKey = "sourceView" static let episodePageKey = "episodePage" static let episodeUuidKey = "episode" @@ -122,12 +123,13 @@ class NavigationManager { if place == NavigationManager.podcastPageKey { guard let data else { return } + let sourceView = data[NavigationManager.sourceViewKey] as? UIView if let podcast = data[NavigationManager.podcastKey] as? Podcast { - mainController?.navigateToPodcast(podcast) + mainController?.navigateToPodcast(podcast, fromSourceView: sourceView) } if let podcastUuid = data[NavigationManager.podcastKey] as? String { if let podcast = DataManager.sharedManager.findPodcast(uuid: podcastUuid, includeUnsubscribed: true) { - mainController?.navigateToPodcast(podcast) + mainController?.navigateToPodcast(podcast, fromSourceView: sourceView) } } else if let podcastInfo = data[NavigationManager.podcastKey] as? PodcastInfo { mainController?.navigateToPodcastInfo(podcastInfo) @@ -148,7 +150,8 @@ class NavigationManager { guard let data else { return } if let folder = data[NavigationManager.folderKey] as? Folder { - mainController?.navigateToFolder(folder, popToRootViewController: (data[NavigationManager.popToRootViewController] as? Bool) ?? true) + let sourceView = data[NavigationManager.sourceViewKey] as? UIView + mainController?.navigateToFolder(folder, popToRootViewController: (data[NavigationManager.popToRootViewController] as? Bool) ?? true, fromSourceView: sourceView) } } else if place == NavigationManager.episodePageKey { guard let data, let uuid = data[NavigationManager.episodeUuidKey] as? String else { return } diff --git a/podcasts/Main/NavigationProtocol.swift b/podcasts/Main/NavigationProtocol.swift index 21ace7693e..f75329649d 100644 --- a/podcasts/Main/NavigationProtocol.swift +++ b/podcasts/Main/NavigationProtocol.swift @@ -5,11 +5,11 @@ import UIKit protocol NavigationProtocol: AnyObject { func navigateToPodcastList(_ animated: Bool) - func navigateToPodcast(_ podcast: Podcast) + func navigateToPodcast(_ podcast: Podcast, fromSourceView sourceView: UIView?) func navigateToPodcastInfo(_ podcastInfo: PodcastInfo) func navigateTo(podcast searchResult: PodcastFolderSearchResult) - func navigateToFolder(_ folder: Folder, popToRootViewController: Bool) + func navigateToFolder(_ folder: Folder, popToRootViewController: Bool, fromSourceView sourceView: UIView?) func navigateToSuggestedFolders() func navigateToEpisode(_ episodeUuid: String, podcastUuid: String?, timestamp: TimeInterval?) diff --git a/podcasts/Podcasts/All Podcasts/PodcastListViewController+CollectionView.swift b/podcasts/Podcasts/All Podcasts/PodcastListViewController+CollectionView.swift index 59d4982e3e..ed8498744e 100644 --- a/podcasts/Podcasts/All Podcasts/PodcastListViewController+CollectionView.swift +++ b/podcasts/Podcasts/All Podcasts/PodcastListViewController+CollectionView.swift @@ -108,12 +108,23 @@ extension PodcastListViewController: UICollectionViewDelegate, UICollectionViewD return } + let isGridLayout = Settings.libraryType() != .list + let sourceCell = isGridLayout ? collectionView.cellForItem(at: indexPath) : nil + if let podcast = selectedItem?.podcast { Analytics.track(.podcastsListPodcastTapped) - NavigationManager.sharedManager.navigateTo(NavigationManager.podcastPageKey, data: [NavigationManager.podcastKey: podcast]) + let data: NSMutableDictionary = [NavigationManager.podcastKey: podcast] + if let sourceCell { + data[NavigationManager.sourceViewKey] = sourceCell + } + NavigationManager.sharedManager.navigateTo(NavigationManager.podcastPageKey, data: data) } else if let folder = selectedItem?.folder { Analytics.track(.podcastsListFolderTapped) - NavigationManager.sharedManager.navigateTo(NavigationManager.folderPageKey, data: [NavigationManager.folderKey: folder]) + let data: NSMutableDictionary = [NavigationManager.folderKey: folder] + if let sourceCell { + data[NavigationManager.sourceViewKey] = sourceCell + } + NavigationManager.sharedManager.navigateTo(NavigationManager.folderPageKey, data: data) } }