From 5294481eda57448f0f9a412a2fb7648fd43197d4 Mon Sep 17 00:00:00 2001 From: Yusaku Nishi Date: Sun, 17 Dec 2023 21:53:07 +0900 Subject: [PATCH 1/8] update: grid layout demo for iPad --- .../Samples/Grid/ImageGridView.swift | 27 ++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/Demo/MediaViewerDemo/Samples/Grid/ImageGridView.swift b/Demo/MediaViewerDemo/Samples/Grid/ImageGridView.swift index 78341f18..07ce25a0 100644 --- a/Demo/MediaViewerDemo/Samples/Grid/ImageGridView.swift +++ b/Demo/MediaViewerDemo/Samples/Grid/ImageGridView.swift @@ -12,10 +12,24 @@ final class ImageGridView: UIView { let collectionView: UICollectionView = { let layout = UICollectionViewCompositionalLayout { _, layoutEnvironment in - let columnCount = 3 - let itemSpacing = 2.0 + let minimumItemWidth: CGFloat + let itemSpacing: CGFloat + let contentInsetsReference: UIContentInsetsReference + switch layoutEnvironment.traitCollection.horizontalSizeClass { + case .unspecified, .compact: + minimumItemWidth = 130 + itemSpacing = 2 + contentInsetsReference = .automatic + case .regular: + minimumItemWidth = 160 + itemSpacing = 16 + contentInsetsReference = .layoutMargins + @unknown default: + fatalError() + } let effectiveFullWidth = layoutEnvironment.container.effectiveContentSize.width + let columnCount = Int(effectiveFullWidth / minimumItemWidth) let totalSpacing = itemSpacing * CGFloat(columnCount - 1) let estimatedItemWidth = (effectiveFullWidth - totalSpacing) / CGFloat(columnCount) let group = NSCollectionLayoutGroup.horizontal( @@ -33,10 +47,16 @@ final class ImageGridView: UIView { let section = NSCollectionLayoutSection(group: group) section.interGroupSpacing = itemSpacing + section.contentInsetsReference = contentInsetsReference return section } - return UICollectionView(frame: .zero, collectionViewLayout: layout) + let collectionView = UICollectionView( + frame: .zero, + collectionViewLayout: layout + ) + collectionView.preservesSuperviewLayoutMargins = true + return collectionView }() // MARK: - Initializers @@ -52,6 +72,7 @@ final class ImageGridView: UIView { } private func setUpViews() { + preservesSuperviewLayoutMargins = true backgroundColor = .systemBackground // Subviews From a338a19460fca157d987e8b2b1b5eaff955a6092 Mon Sep 17 00:00:00 2001 From: Yusaku Nishi Date: Sun, 17 Dec 2023 22:17:18 +0900 Subject: [PATCH 2/8] update: camera layout demo for iPad --- .../Samples/Camera/CameraLikeView.swift | 51 +++++++++++++++---- 1 file changed, 41 insertions(+), 10 deletions(-) diff --git a/Demo/MediaViewerDemo/Samples/Camera/CameraLikeView.swift b/Demo/MediaViewerDemo/Samples/Camera/CameraLikeView.swift index 22dc53f8..b6cfc08b 100644 --- a/Demo/MediaViewerDemo/Samples/Camera/CameraLikeView.swift +++ b/Demo/MediaViewerDemo/Samples/Camera/CameraLikeView.swift @@ -41,6 +41,10 @@ final class CameraLikeView: UIView { return button }() + private let bottomAreaLayoutGuide = UILayoutGuide() + + private let shutterButtonWidth = 68.0 + // MARK: - Initializers override init(frame: CGRect) { @@ -62,10 +66,33 @@ final class CameraLikeView: UIView { addSubview(showLibraryButton) addSubview(toggleTabBarHiddenButton) - let bottomAreaLayoutGuide = UILayoutGuide() addLayoutGuide(bottomAreaLayoutGuide) + shutterButton.layer.cornerRadius = shutterButtonWidth / 2 + // Layout + showLibraryButton.autoLayout { item in + item.leading.equal(to: layoutMarginsGuide) + item.centerY.equal(to: bottomAreaLayoutGuide) + item.size.equal(toSquare: 48) + } + + toggleTabBarHiddenButton.autoLayout { item in + item.trailing.equal(to: layoutMarginsGuide) + item.centerY.equal(to: bottomAreaLayoutGuide) + } + + switch traitCollection.horizontalSizeClass { + case .unspecified, .compact: + layoutForCompactScreen() + case .regular: + layoutForRegularScreen() + @unknown default: + fatalError() + } + } + + private func layoutForCompactScreen() { previewView.autoLayout { item in item.top.equal(to: safeAreaLayoutGuide, plus: 44) item.width.equal(to: item.height, multipliedBy: 3.0 / 4) @@ -78,22 +105,26 @@ final class CameraLikeView: UIView { item.bottom.equal(to: safeAreaLayoutGuide) } - let shutterButtonWidth = 68.0 - shutterButton.layer.cornerRadius = shutterButtonWidth / 2 shutterButton.autoLayout { item in item.center.equal(to: bottomAreaLayoutGuide) item.size.equal(toSquare: shutterButtonWidth) } + } + + private func layoutForRegularScreen() { + previewView.autoLayout { item in + item.edges.equalToSuperview() + } - showLibraryButton.autoLayout { item in - item.leading.equal(to: layoutMarginsGuide) - item.centerY.equal(to: bottomAreaLayoutGuide) - item.size.equal(toSquare: 48) + bottomAreaLayoutGuide.autoLayout { item in + item.leadingTrailing.equalToSuperview() + item.bottom.equal(to: safeAreaLayoutGuide) } - toggleTabBarHiddenButton.autoLayout { item in - item.trailing.equal(to: layoutMarginsGuide) - item.centerY.equal(to: bottomAreaLayoutGuide) + shutterButton.autoLayout { item in + item.centerX.equal(to: bottomAreaLayoutGuide) + item.topBottom.equal(to: bottomAreaLayoutGuide, insetBy: 16) + item.size.equal(toSquare: shutterButtonWidth) } } } From 83ef547850ac93db23e9d75d40f20afef4f01ddd Mon Sep 17 00:00:00 2001 From: Yusaku Nishi Date: Sun, 17 Dec 2023 22:33:17 +0900 Subject: [PATCH 3/8] update: camera demo appearance --- .../Samples/Camera/CameraLikeView.swift | 32 +++++++++++-------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/Demo/MediaViewerDemo/Samples/Camera/CameraLikeView.swift b/Demo/MediaViewerDemo/Samples/Camera/CameraLikeView.swift index b6cfc08b..e23c76da 100644 --- a/Demo/MediaViewerDemo/Samples/Camera/CameraLikeView.swift +++ b/Demo/MediaViewerDemo/Samples/Camera/CameraLikeView.swift @@ -41,7 +41,11 @@ final class CameraLikeView: UIView { return button }() - private let bottomAreaLayoutGuide = UILayoutGuide() + private let buttonArea: UIView = { + let view = UIView() + view.backgroundColor = .black.withAlphaComponent(0.1) + return view + }() private let shutterButtonWidth = 68.0 @@ -62,24 +66,23 @@ final class CameraLikeView: UIView { // Subviews addSubview(previewView) - addSubview(shutterButton) - addSubview(showLibraryButton) - addSubview(toggleTabBarHiddenButton) - - addLayoutGuide(bottomAreaLayoutGuide) + addSubview(buttonArea) + buttonArea.addSubview(shutterButton) + buttonArea.addSubview(showLibraryButton) + buttonArea.addSubview(toggleTabBarHiddenButton) shutterButton.layer.cornerRadius = shutterButtonWidth / 2 // Layout showLibraryButton.autoLayout { item in item.leading.equal(to: layoutMarginsGuide) - item.centerY.equal(to: bottomAreaLayoutGuide) + item.centerY.equal(to: shutterButton) item.size.equal(toSquare: 48) } toggleTabBarHiddenButton.autoLayout { item in item.trailing.equal(to: layoutMarginsGuide) - item.centerY.equal(to: bottomAreaLayoutGuide) + item.centerY.equal(to: shutterButton) } switch traitCollection.horizontalSizeClass { @@ -99,14 +102,14 @@ final class CameraLikeView: UIView { item.leadingTrailing.equalToSuperview() } - bottomAreaLayoutGuide.autoLayout { item in + buttonArea.autoLayout { item in item.top.equal(to: previewView.bottomAnchor) item.leadingTrailing.equalToSuperview() item.bottom.equal(to: safeAreaLayoutGuide) } shutterButton.autoLayout { item in - item.center.equal(to: bottomAreaLayoutGuide) + item.center.equalToSuperview() item.size.equal(toSquare: shutterButtonWidth) } } @@ -116,14 +119,15 @@ final class CameraLikeView: UIView { item.edges.equalToSuperview() } - bottomAreaLayoutGuide.autoLayout { item in + buttonArea.autoLayout { item in item.leadingTrailing.equalToSuperview() - item.bottom.equal(to: safeAreaLayoutGuide) + item.bottom.equalToSuperview() } shutterButton.autoLayout { item in - item.centerX.equal(to: bottomAreaLayoutGuide) - item.topBottom.equal(to: bottomAreaLayoutGuide, insetBy: 16) + item.centerX.equalToSuperview() + item.top.equalToSuperview(plus: 16) + item.bottom.equal(to: safeAreaLayoutGuide, plus: -16) item.size.equal(toSquare: shutterButtonWidth) } } From e8544c085a2ebde349aeceb18180f5e23b0776cc Mon Sep 17 00:00:00 2001 From: Yusaku Nishi Date: Sun, 24 Dec 2023 03:00:03 +0900 Subject: [PATCH 4/8] fix: toolbar animation on the push transition --- .../Transitions/MediaViewerTransition.swift | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/Sources/MediaViewer/Transitions/MediaViewerTransition.swift b/Sources/MediaViewer/Transitions/MediaViewerTransition.swift index 91ecd30a..1492e758 100644 --- a/Sources/MediaViewer/Transitions/MediaViewerTransition.swift +++ b/Sources/MediaViewer/Transitions/MediaViewerTransition.swift @@ -157,10 +157,12 @@ final class MediaViewerTransition: NSObject, UIViewControllerAnimatedTransitioni } var viewsToFadeDuringTransition = mediaViewer.subviewsToFadeDuringTransition - viewsToFadeDuringTransition.append(toolbar) if wasTabBarHidden { viewsToFadeDuringTransition.append(mediaViewer.pageControlToolbar) } + if mediaViewer.toolbarHiddenBackup { + viewsToFadeDuringTransition.append(toolbar) + } for view in viewsToFadeDuringTransition { view.alpha = 0 } @@ -188,6 +190,17 @@ final class MediaViewerTransition: NSObject, UIViewControllerAnimatedTransitioni currentPageImageView.contentMode = sourceView.contentMode } currentPageImageView.layer.masksToBounds = true + + /* + * [Workaround] + * If the tabBar becomes hidden and the toolbar remains visible, + * move it manually because repositioning is not animated. + */ + if !mediaViewer.toolbarHiddenBackup, + let tabBar, + tabBarHiddenBackup! { + toolbar.frame.origin.y = tabBar.frame.origin.y + } } animator.addCompletion { position in defer { transitionContext.completeTransition() } From 8bd980eeb391b72de3f6a206f0707ebdbc016cc6 Mon Sep 17 00:00:00 2001 From: Yusaku Nishi Date: Sun, 24 Dec 2023 03:29:24 +0900 Subject: [PATCH 5/8] fix: toolbar animation on the pop transition --- .../Transitions/MediaViewerTransition.swift | 21 ++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/Sources/MediaViewer/Transitions/MediaViewerTransition.swift b/Sources/MediaViewer/Transitions/MediaViewerTransition.swift index 1492e758..7c24fb6e 100644 --- a/Sources/MediaViewer/Transitions/MediaViewerTransition.swift +++ b/Sources/MediaViewer/Transitions/MediaViewerTransition.swift @@ -256,7 +256,9 @@ final class MediaViewerTransition: NSObject, UIViewControllerAnimatedTransitioni assert(toolbar.layer.animationKeys() == nil) // [Workaround] Prevent toVC.toolbarItems from showing up during transition. - toVC.toolbarItems = nil + if mediaViewer.toolbarHiddenBackup { + toVC.toolbarItems = nil + } /* * [Workaround] @@ -295,10 +297,10 @@ final class MediaViewerTransition: NSObject, UIViewControllerAnimatedTransitioni let tabBar = toVC.tabBarController?.tabBar let isTabBarHidden = tabBar?.isHidden ?? true if isTabBarHidden { - viewsToFadeDuringTransition.append(contentsOf: [ - toolbar, - mediaViewer.pageControlToolbar - ]) + if mediaViewer.toolbarHiddenBackup { + viewsToFadeDuringTransition.append(toolbar) + } + viewsToFadeDuringTransition.append(mediaViewer.pageControlToolbar) } // MARK: Animation @@ -320,6 +322,15 @@ final class MediaViewerTransition: NSObject, UIViewControllerAnimatedTransitioni currentPageImageView.alpha = 0 } currentPageImageView.clipsToBounds = true // TODO: Change according to the source configuration + + /* + * [Workaround] + * If the tabBar becomes visible and the toolbar remains visible, + * move it manually because repositioning is not animated. + */ + if !mediaViewer.toolbarHiddenBackup, let tabBar { + toolbar.frame.origin.y = tabBar.frame.origin.y - toolbar.bounds.height + } } // Customize the tabBar animation From 3842c4ec189dc3b9909aacd1be04ccec9b63e49a Mon Sep 17 00:00:00 2001 From: Yusaku Nishi Date: Sun, 24 Dec 2023 03:33:56 +0900 Subject: [PATCH 6/8] fix: toolbar animation on the interactive pop transition --- .../MediaViewerInteractivePopTransition.swift | 21 ++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/Sources/MediaViewer/Transitions/MediaViewerInteractivePopTransition.swift b/Sources/MediaViewer/Transitions/MediaViewerInteractivePopTransition.swift index 04efcabb..b61c9dda 100644 --- a/Sources/MediaViewer/Transitions/MediaViewerInteractivePopTransition.swift +++ b/Sources/MediaViewer/Transitions/MediaViewerInteractivePopTransition.swift @@ -131,7 +131,9 @@ extension MediaViewerInteractivePopTransition: UIViewControllerInteractiveTransi : 1 // [Workaround] Prevent toVC.toolbarItems from showing up during transition. - toVC.toolbarItems = nil + if mediaViewer.toolbarHiddenBackup { + toVC.toolbarItems = nil + } /* * [Workaround] @@ -152,10 +154,10 @@ extension MediaViewerInteractivePopTransition: UIViewControllerInteractiveTransi var viewsToFadeDuringTransition = mediaViewer.subviewsToFadeDuringTransition let isTabBarHidden = tabBar?.isHidden ?? true if isTabBarHidden { - viewsToFadeDuringTransition.append(contentsOf: [ - toolbar, - mediaViewer.pageControlToolbar - ]) + if mediaViewer.toolbarHiddenBackup { + viewsToFadeDuringTransition.append(toolbar) + } + viewsToFadeDuringTransition.append(mediaViewer.pageControlToolbar) } mediaViewer.willStartInteractivePopTransition() @@ -186,6 +188,15 @@ extension MediaViewerInteractivePopTransition: UIViewControllerInteractiveTransi width: pageControlToolbarFrame.width, height: 0 ) + + /* + * [Workaround] + * If the tabBar becomes visible and the toolbar remains visible, + * move it manually because repositioning is not animated. + */ + if !mediaViewer.toolbarHiddenBackup, let tabBar = self.tabBar { + toolbar.frame.origin.y = tabBar.frame.origin.y - toolbar.bounds.height + } } } From c8771c3bc54823470944c54c2aaa441b77cd2c09 Mon Sep 17 00:00:00 2001 From: Yusaku Nishi Date: Sun, 24 Dec 2023 03:39:47 +0900 Subject: [PATCH 7/8] chore: add toggleToolbarButton to demo --- .../Grid/SyncImagesViewController.swift | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/Demo/MediaViewerDemo/Samples/Grid/SyncImagesViewController.swift b/Demo/MediaViewerDemo/Samples/Grid/SyncImagesViewController.swift index 32f06965..0aaeb948 100644 --- a/Demo/MediaViewerDemo/Samples/Grid/SyncImagesViewController.swift +++ b/Demo/MediaViewerDemo/Samples/Grid/SyncImagesViewController.swift @@ -60,6 +60,17 @@ final class SyncImagesViewController: UIViewController { } ) + private lazy var toggleToolbarButton = UIBarButtonItem( + title: "Toggle Toolbar", + primaryAction: .init { [weak self] _ in + guard let self, let navigationController else { return } + navigationController.setToolbarHidden( + !navigationController.isToolbarHidden, + animated: true + ) + } + ) + // MARK: - Lifecycle override func loadView() { @@ -79,6 +90,14 @@ final class SyncImagesViewController: UIViewController { navigationItem.title = "Sync Sample" navigationItem.backButtonDisplayMode = .minimal navigationItem.leftBarButtonItem = refreshButton + navigationItem.rightBarButtonItem = toggleToolbarButton + + // Toolbar + toolbarItems = [ + .flexibleSpace(), + .init(title: "Toolbar"), + .flexibleSpace() + ] // Subviews imageGridView.collectionView.refreshControl = .init( From 4f9d9f0f2eb45290b1bc0f2dc2433bbdd69249bd Mon Sep 17 00:00:00 2001 From: Yusaku Nishi Date: Sun, 24 Dec 2023 03:45:19 +0900 Subject: [PATCH 8/8] docs: README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ad0bd975..c3440833 100644 --- a/README.md +++ b/README.md @@ -60,7 +60,7 @@ See demo for more detailed usage. To use the `MediaViewer` library in a SwiftPM project, add the following line to the dependencies in your `Package.swift` file: ```swift -.package(url: "https://github.com/jrsaruo/MediaViewer", from: "0.1.1"), +.package(url: "https://github.com/jrsaruo/MediaViewer", from: "0.1.2"), ``` and add `MediaViewer` as a dependency for your target: