From cff048c2a3271d8eaf9c5dcd0348c02ab8d0f82b Mon Sep 17 00:00:00 2001 From: CMK Date: Fri, 31 Dec 2021 17:31:13 +0800 Subject: [PATCH] feat: add shadow and fix modal transition issue --- Mastodon.xcodeproj/project.pbxproj | 4 ++ Mastodon/Coordinator/SceneCoordinator.swift | 22 +++----- .../OnboardingNavigationController.swift | 50 +++++++++++++++++ .../View/WelcomeIllustrationView.swift | 2 +- .../Welcome/WelcomeViewController.swift | 54 +++++++++++++------ ...veStatusBarStyleNavigationController.swift | 2 +- 6 files changed, 103 insertions(+), 31 deletions(-) create mode 100644 Mastodon/Scene/Onboarding/Share/OnboardingNavigationController.swift diff --git a/Mastodon.xcodeproj/project.pbxproj b/Mastodon.xcodeproj/project.pbxproj index bb7a8a4f..8f0bfafa 100644 --- a/Mastodon.xcodeproj/project.pbxproj +++ b/Mastodon.xcodeproj/project.pbxproj @@ -192,6 +192,7 @@ DB03F7F52689B782007B274C /* ComposeTableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB03F7F42689B782007B274C /* ComposeTableView.swift */; }; DB040ED126538E3D00BEE9D8 /* Trie.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB040ED026538E3C00BEE9D8 /* Trie.swift */; }; DB0617EB277EF3820030EE79 /* GradientBorderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB0617EA277EF3820030EE79 /* GradientBorderView.swift */; }; + DB0617ED277F02C50030EE79 /* OnboardingNavigationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB0617EC277F02C50030EE79 /* OnboardingNavigationController.swift */; }; DB084B5725CBC56C00F898ED /* Status.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB084B5625CBC56C00F898ED /* Status.swift */; }; DB0AC6FC25CD02E600D75117 /* APIService+Instance.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB0AC6FB25CD02E600D75117 /* APIService+Instance.swift */; }; DB0C946526A6FD4D0088FB11 /* AlamofireImage in Frameworks */ = {isa = PBXBuildFile; productRef = DB0C946426A6FD4D0088FB11 /* AlamofireImage */; }; @@ -971,6 +972,7 @@ DB03F7F42689B782007B274C /* ComposeTableView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComposeTableView.swift; sourceTree = ""; }; DB040ED026538E3C00BEE9D8 /* Trie.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Trie.swift; sourceTree = ""; }; DB0617EA277EF3820030EE79 /* GradientBorderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GradientBorderView.swift; sourceTree = ""; }; + DB0617EC277F02C50030EE79 /* OnboardingNavigationController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingNavigationController.swift; sourceTree = ""; }; DB084B5625CBC56C00F898ED /* Status.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Status.swift; sourceTree = ""; }; DB0AC6FB25CD02E600D75117 /* APIService+Instance.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "APIService+Instance.swift"; sourceTree = ""; }; DB0C946A26A700AB0088FB11 /* MastodonUser+Property.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MastodonUser+Property.swift"; sourceTree = ""; }; @@ -2521,6 +2523,7 @@ 2D82B9FE25E7863200E36F0F /* OnboardingViewControllerAppearance.swift */, DB2F073325E8ECF000957B2D /* AuthenticationViewModel.swift */, DB029E94266A20430062874E /* MastodonAuthenticationController.swift */, + DB0617EC277F02C50030EE79 /* OnboardingNavigationController.swift */, ); path = Share; sourceTree = ""; @@ -3971,6 +3974,7 @@ DBF156DF2701B17600EC00B7 /* SidebarAddAccountCollectionViewCell.swift in Sources */, DB789A0B25F9F2950071ACA0 /* ComposeViewController.swift in Sources */, DB938F0926240F3C00E5B6C1 /* RemoteThreadViewModel.swift in Sources */, + DB0617ED277F02C50030EE79 /* OnboardingNavigationController.swift in Sources */, DBBC24AE26A53DC100398BB9 /* ReplicaStatusView.swift in Sources */, DB75BF1E263C1C1B00EDBF1F /* CustomScheduler.swift in Sources */, 0FAA102725E1126A0017CCDE /* MastodonPickServerViewController.swift in Sources */, diff --git a/Mastodon/Coordinator/SceneCoordinator.swift b/Mastodon/Coordinator/SceneCoordinator.swift index d3591ab4..49504fd1 100644 --- a/Mastodon/Coordinator/SceneCoordinator.swift +++ b/Mastodon/Coordinator/SceneCoordinator.swift @@ -304,20 +304,14 @@ extension SceneCoordinator { presentingViewController.showDetailViewController(navigationController, sender: sender) case .modal(let animated, let completion): -// let modalNavigationController: UINavigationController = { -// if scene.isOnboarding { -// return AdaptiveStatusBarStyleNavigationController(rootViewController: viewController) -// } else { -// return UINavigationController(rootViewController: viewController) -// } -// }() -// modalNavigationController.modalPresentationCapturesStatusBarAppearance = true -// if let adaptivePresentationControllerDelegate = viewController as? UIAdaptivePresentationControllerDelegate { -// modalNavigationController.presentationController?.delegate = adaptivePresentationControllerDelegate -// } -// presentingViewController.present(modalNavigationController, animated: animated, completion: completion) - - let modalNavigationController = UINavigationController(rootViewController: viewController) + let modalNavigationController: UINavigationController = { + if scene.isOnboarding { + return OnboardingNavigationController(rootViewController: viewController) + } else { + return UINavigationController(rootViewController: viewController) + } + }() + modalNavigationController.modalPresentationCapturesStatusBarAppearance = true if let adaptivePresentationControllerDelegate = viewController as? UIAdaptivePresentationControllerDelegate { modalNavigationController.presentationController?.delegate = adaptivePresentationControllerDelegate } diff --git a/Mastodon/Scene/Onboarding/Share/OnboardingNavigationController.swift b/Mastodon/Scene/Onboarding/Share/OnboardingNavigationController.swift new file mode 100644 index 00000000..07e58b58 --- /dev/null +++ b/Mastodon/Scene/Onboarding/Share/OnboardingNavigationController.swift @@ -0,0 +1,50 @@ +// +// OnboardingNavigationController.swift +// Mastodon +// +// Created by MainasuK on 2021-12-31. +// + +import UIKit + +final class OnboardingNavigationController: AdaptiveStatusBarStyleNavigationController { + + private(set) lazy var gradientBorderView = GradientBorderView(frame: view.bounds) + +} + +extension OnboardingNavigationController { + + override func viewDidLoad() { + super.viewDidLoad() + + gradientBorderView.translatesAutoresizingMaskIntoConstraints = false + view.addSubview(gradientBorderView) + NSLayoutConstraint.activate([ + gradientBorderView.topAnchor.constraint(equalTo: view.topAnchor), + gradientBorderView.leadingAnchor.constraint(equalTo: view.leadingAnchor), + gradientBorderView.trailingAnchor.constraint(equalTo: view.trailingAnchor), + gradientBorderView.bottomAnchor.constraint(equalTo: view.bottomAnchor), + ]) + + updateBorderViewDisplay() + } + + override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) { + super.traitCollectionDidChange(previousTraitCollection) + + } + +} + +extension OnboardingNavigationController { + + private func updateBorderViewDisplay() { + switch traitCollection.userInterfaceIdiom { + case .phone: + gradientBorderView.isHidden = true + default: + gradientBorderView.isHidden = false + } + } +} diff --git a/Mastodon/Scene/Onboarding/Welcome/View/WelcomeIllustrationView.swift b/Mastodon/Scene/Onboarding/Welcome/View/WelcomeIllustrationView.swift index cb7ac768..23fa1505 100644 --- a/Mastodon/Scene/Onboarding/Welcome/View/WelcomeIllustrationView.swift +++ b/Mastodon/Scene/Onboarding/Welcome/View/WelcomeIllustrationView.swift @@ -55,7 +55,7 @@ extension WelcomeIllustrationView { var artworkImageSize: CGSize { switch self { case .compact: return CGSize(width: 375, height: 1500) - case .regular: return CGSize(width: 547, height: 1500) + case .regular: return CGSize(width: 547, height: 3000) } } } diff --git a/Mastodon/Scene/Onboarding/Welcome/WelcomeViewController.swift b/Mastodon/Scene/Onboarding/Welcome/WelcomeViewController.swift index d450764e..c86b059b 100644 --- a/Mastodon/Scene/Onboarding/Welcome/WelcomeViewController.swift +++ b/Mastodon/Scene/Onboarding/Welcome/WelcomeViewController.swift @@ -57,7 +57,7 @@ final class WelcomeViewController: UIViewController, NeedsDependency { return button }() - private(set) lazy var signInButton: UIButton = { + private(set) lazy var signInButton: PrimaryActionButton = { let button = PrimaryActionButton() button.adjustsBackgroundImageWhenUserInterfaceStyleChanges = false button.titleLabel?.font = UIFontMetrics(forTextStyle: .headline).scaledFont(for: .systemFont(ofSize: 15, weight: .semibold)) @@ -66,12 +66,12 @@ final class WelcomeViewController: UIViewController, NeedsDependency { let backgroundImageHighlightedColor = Asset.Scene.Welcome.signInButtonBackground.color.withAlphaComponent(0.8) button.setBackgroundImage(.placeholder(color: backgroundImageColor), for: .normal) button.setBackgroundImage(.placeholder(color: backgroundImageHighlightedColor), for: .highlighted) - let titleColor: UIColor = UIColor.white.withAlphaComponent(0.8) + let titleColor: UIColor = UIColor.white.withAlphaComponent(0.9) button.setTitleColor(titleColor, for: .normal) return button }() + let signInButtonShadowView = UIView() - private(set) lazy var gradientBorderView = GradientBorderView(frame: view.bounds) deinit { os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s", ((#file as NSString).lastPathComponent), #line, #function) @@ -117,13 +117,14 @@ extension WelcomeViewController { signInButton.heightAnchor.constraint(equalToConstant: WelcomeViewController.actionButtonHeight).priority(.required - 1), ]) - gradientBorderView.translatesAutoresizingMaskIntoConstraints = false - view.addSubview(gradientBorderView) + signInButtonShadowView.translatesAutoresizingMaskIntoConstraints = false + buttonContainer.addSubview(signInButtonShadowView) + buttonContainer.sendSubviewToBack(signInButtonShadowView) NSLayoutConstraint.activate([ - gradientBorderView.topAnchor.constraint(equalTo: view.topAnchor), - gradientBorderView.leadingAnchor.constraint(equalTo: view.leadingAnchor), - gradientBorderView.trailingAnchor.constraint(equalTo: view.trailingAnchor), - gradientBorderView.bottomAnchor.constraint(equalTo: view.bottomAnchor), + signInButtonShadowView.topAnchor.constraint(equalTo: signInButton.topAnchor), + signInButtonShadowView.leadingAnchor.constraint(equalTo: signInButton.leadingAnchor), + signInButtonShadowView.trailingAnchor.constraint(equalTo: signInButton.trailingAnchor), + signInButtonShadowView.bottomAnchor.constraint(equalTo: signInButton.bottomAnchor), ]) signUpButton.addTarget(self, action: #selector(signUpButtonDidClicked(_:)), for: .touchUpInside) @@ -138,6 +139,12 @@ extension WelcomeViewController { .store(in: &disposeBag) } + override func viewDidLayoutSubviews() { + super.viewDidLayoutSubviews() + + setupButtonShadowView() + } + override func viewSafeAreaInsetsDidChange() { super.viewSafeAreaInsetsDidChange() @@ -153,12 +160,27 @@ extension WelcomeViewController { super.traitCollectionDidChange(previousTraitCollection) setupIllustrationLayout() + setupButtonShadowView() } } extension WelcomeViewController { + private func setupButtonShadowView() { + signInButtonShadowView.layer.setupShadow( + color: .black, + alpha: 0.25, + x: 0, + y: 1, + blur: 2, + spread: 0, + roundedRect: signInButtonShadowView.bounds, + byRoundingCorners: .allCorners, + cornerRadii: CGSize(width: 10, height: 10) + ) + } + private func updateButtonContainerLayoutMargins(traitCollection: UITraitCollection) { switch traitCollection.userInterfaceIdiom { case .phone: @@ -320,21 +342,23 @@ extension WelcomeViewController: UIAdaptivePresentationControllerDelegate { func adaptivePresentationStyle(for controller: UIPresentationController, traitCollection: UITraitCollection) -> UIModalPresentationStyle { logger.log(level: .debug, "\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public)") + // update button layout updateButtonContainerLayoutMargins(traitCollection: traitCollection) - + + let navigationController = navigationController as? OnboardingNavigationController + switch traitCollection.userInterfaceIdiom { case .phone: + navigationController?.gradientBorderView.isHidden = true // make underneath view controller alive to fix layout issue due to view life cycle return .fullScreen default: switch traitCollection.horizontalSizeClass { case .compact: + navigationController?.gradientBorderView.isHidden = true return .fullScreen - case .regular: - return .formSheet - case .unspecified: - return .formSheet - @unknown default: + default: + navigationController?.gradientBorderView.isHidden = false return .formSheet } } diff --git a/Mastodon/Scene/Share/NavigationController/AdaptiveStatusBarStyleNavigationController.swift b/Mastodon/Scene/Share/NavigationController/AdaptiveStatusBarStyleNavigationController.swift index eb260853..aac23285 100644 --- a/Mastodon/Scene/Share/NavigationController/AdaptiveStatusBarStyleNavigationController.swift +++ b/Mastodon/Scene/Share/NavigationController/AdaptiveStatusBarStyleNavigationController.swift @@ -9,7 +9,7 @@ import UIKit // Make status bar style adaptive for child view controller // SeeAlso: `modalPresentationCapturesStatusBarAppearance` -final class AdaptiveStatusBarStyleNavigationController: UINavigationController { +class AdaptiveStatusBarStyleNavigationController: UINavigationController { override var childForStatusBarStyle: UIViewController? { visibleViewController }