feat: add shadow and fix modal transition issue

This commit is contained in:
CMK 2021-12-31 17:31:13 +08:00
parent 4a38daa345
commit cff048c2a3
6 changed files with 103 additions and 31 deletions

View File

@ -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 = "<group>"; };
DB040ED026538E3C00BEE9D8 /* Trie.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Trie.swift; sourceTree = "<group>"; };
DB0617EA277EF3820030EE79 /* GradientBorderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GradientBorderView.swift; sourceTree = "<group>"; };
DB0617EC277F02C50030EE79 /* OnboardingNavigationController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingNavigationController.swift; sourceTree = "<group>"; };
DB084B5625CBC56C00F898ED /* Status.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Status.swift; sourceTree = "<group>"; };
DB0AC6FB25CD02E600D75117 /* APIService+Instance.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "APIService+Instance.swift"; sourceTree = "<group>"; };
DB0C946A26A700AB0088FB11 /* MastodonUser+Property.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MastodonUser+Property.swift"; sourceTree = "<group>"; };
@ -2521,6 +2523,7 @@
2D82B9FE25E7863200E36F0F /* OnboardingViewControllerAppearance.swift */,
DB2F073325E8ECF000957B2D /* AuthenticationViewModel.swift */,
DB029E94266A20430062874E /* MastodonAuthenticationController.swift */,
DB0617EC277F02C50030EE79 /* OnboardingNavigationController.swift */,
);
path = Share;
sourceTree = "<group>";
@ -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 */,

View File

@ -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
}

View File

@ -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
}
}
}

View File

@ -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)
}
}
}

View File

@ -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
}
}

View File

@ -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
}