chore: update onboarding layout for iPad
This commit is contained in:
parent
bcf0262608
commit
6b1d3f8738
|
@ -7,12 +7,12 @@
|
|||
<key>AppShared.xcscheme_^#shared#^_</key>
|
||||
<dict>
|
||||
<key>orderHint</key>
|
||||
<integer>56</integer>
|
||||
<integer>35</integer>
|
||||
</dict>
|
||||
<key>CoreDataStack.xcscheme_^#shared#^_</key>
|
||||
<dict>
|
||||
<key>orderHint</key>
|
||||
<integer>54</integer>
|
||||
<integer>38</integer>
|
||||
</dict>
|
||||
<key>Mastodon - ASDK.xcscheme_^#shared#^_</key>
|
||||
<dict>
|
||||
|
@ -97,7 +97,7 @@
|
|||
<key>MastodonIntent.xcscheme_^#shared#^_</key>
|
||||
<dict>
|
||||
<key>orderHint</key>
|
||||
<integer>51</integer>
|
||||
<integer>36</integer>
|
||||
</dict>
|
||||
<key>MastodonIntents.xcscheme_^#shared#^_</key>
|
||||
<dict>
|
||||
|
@ -117,7 +117,7 @@
|
|||
<key>ShareActionExtension.xcscheme_^#shared#^_</key>
|
||||
<dict>
|
||||
<key>orderHint</key>
|
||||
<integer>55</integer>
|
||||
<integer>37</integer>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>SuppressBuildableAutocreation</key>
|
||||
|
|
|
@ -214,7 +214,13 @@ extension SceneCoordinator {
|
|||
assertionFailure()
|
||||
return nil
|
||||
}
|
||||
presentingViewController.presentPanModal(panModalPresentable)
|
||||
|
||||
// https://github.com/slackhq/PanModal/issues/74#issuecomment-572426441
|
||||
panModalPresentable.modalPresentationStyle = .custom
|
||||
panModalPresentable.modalPresentationCapturesStatusBarAppearance = true
|
||||
panModalPresentable.transitioningDelegate = PanModalPresentationDelegate.default
|
||||
presentingViewController.present(panModalPresentable, animated: true, completion: nil)
|
||||
//presentingViewController.presentPanModal(panModalPresentable)
|
||||
|
||||
case .custom(let transitioningDelegate):
|
||||
viewController.modalPresentationStyle = .custom
|
||||
|
|
|
@ -20,6 +20,8 @@ final class MastodonConfirmEmailViewController: UIViewController, NeedsDependenc
|
|||
|
||||
var viewModel: MastodonConfirmEmailViewModel!
|
||||
|
||||
let stackView = UIStackView()
|
||||
|
||||
let largeTitleLabel: UILabel = {
|
||||
let label = UILabel()
|
||||
label.font = UIFontMetrics(forTextStyle: .largeTitle).scaledFont(for: UIFont.systemFont(ofSize: 34, weight: .bold))
|
||||
|
@ -72,9 +74,10 @@ extension MastodonConfirmEmailViewController {
|
|||
override func viewDidLoad() {
|
||||
|
||||
setupOnboardingAppearance()
|
||||
configureTitleLabel()
|
||||
configureMargin()
|
||||
|
||||
// stackView
|
||||
let stackView = UIStackView()
|
||||
stackView.axis = .vertical
|
||||
stackView.distribution = .fill
|
||||
stackView.spacing = 10
|
||||
|
@ -92,8 +95,8 @@ extension MastodonConfirmEmailViewController {
|
|||
stackView.translatesAutoresizingMaskIntoConstraints = false
|
||||
NSLayoutConstraint.activate([
|
||||
stackView.topAnchor.constraint(equalTo: view.readableContentGuide.topAnchor),
|
||||
stackView.leadingAnchor.constraint(equalTo: view.readableContentGuide.leadingAnchor),
|
||||
stackView.trailingAnchor.constraint(equalTo: view.readableContentGuide.trailingAnchor),
|
||||
stackView.leadingAnchor.constraint(equalTo: view.layoutMarginsGuide.leadingAnchor),
|
||||
stackView.trailingAnchor.constraint(equalTo: view.layoutMarginsGuide.trailingAnchor),
|
||||
stackView.bottomAnchor.constraint(equalTo: view.readableContentGuide.bottomAnchor),
|
||||
])
|
||||
NSLayoutConstraint.activate([
|
||||
|
@ -139,6 +142,38 @@ extension MastodonConfirmEmailViewController {
|
|||
.store(in: &self.disposeBag)
|
||||
}
|
||||
|
||||
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
|
||||
super.traitCollectionDidChange(previousTraitCollection)
|
||||
|
||||
configureTitleLabel()
|
||||
configureMargin()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension MastodonConfirmEmailViewController {
|
||||
private func configureTitleLabel() {
|
||||
switch traitCollection.horizontalSizeClass {
|
||||
case .regular:
|
||||
navigationItem.largeTitleDisplayMode = .always
|
||||
navigationItem.title = L10n.Scene.ConfirmEmail.title.replacingOccurrences(of: "\n", with: " ")
|
||||
largeTitleLabel.isHidden = true
|
||||
default:
|
||||
navigationItem.largeTitleDisplayMode = .never
|
||||
navigationItem.title = nil
|
||||
largeTitleLabel.isHidden = false
|
||||
}
|
||||
}
|
||||
|
||||
private func configureMargin() {
|
||||
switch traitCollection.horizontalSizeClass {
|
||||
case .regular:
|
||||
let margin = MastodonConfirmEmailViewController.viewEdgeMargin
|
||||
stackView.layoutMargins = UIEdgeInsets(top: 18, left: margin, bottom: 23, right: margin)
|
||||
default:
|
||||
stackView.layoutMargins = UIEdgeInsets(top: 10, left: 0, bottom: 23, right: 0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension MastodonConfirmEmailViewController {
|
||||
|
|
|
@ -29,6 +29,8 @@ final class MastodonPickServerViewController: UIViewController, NeedsDependency
|
|||
private var expandServerDomainSet = Set<String>()
|
||||
|
||||
private let emptyStateView = PickServerEmptyStateView()
|
||||
private var emptyStateViewLeadingLayoutConstraint: NSLayoutConstraint!
|
||||
private var emptyStateViewTrailingLayoutConstraint: NSLayoutConstraint!
|
||||
let tableViewTopPaddingView = UIView() // fix empty state view background display when tableView bounce scrolling
|
||||
var tableViewTopPaddingViewHeightLayoutConstraint: NSLayoutConstraint!
|
||||
|
||||
|
@ -52,13 +54,14 @@ final class MastodonPickServerViewController: UIViewController, NeedsDependency
|
|||
return tableView
|
||||
}()
|
||||
|
||||
let buttonContainer = UIView()
|
||||
let nextStepButton: PrimaryActionButton = {
|
||||
let button = PrimaryActionButton()
|
||||
button.setTitle(L10n.Common.Controls.Actions.signUp, for: .normal)
|
||||
button.translatesAutoresizingMaskIntoConstraints = false
|
||||
return button
|
||||
}()
|
||||
var nextStepButtonBottomLayoutConstraint: NSLayoutConstraint!
|
||||
var buttonContainerBottomLayoutConstraint: NSLayoutConstraint!
|
||||
|
||||
var mastodonAuthenticationController: MastodonAuthenticationController?
|
||||
|
||||
|
@ -77,6 +80,8 @@ extension MastodonPickServerViewController {
|
|||
|
||||
setupOnboardingAppearance()
|
||||
defer { setupNavigationBarBackgroundView() }
|
||||
configureTitleLabel()
|
||||
configureMargin()
|
||||
|
||||
#if DEBUG
|
||||
navigationItem.rightBarButtonItem = UIBarButtonItem(image: UIImage(systemName: "ellipsis.circle"), style: .plain, target: nil, action: nil)
|
||||
|
@ -89,14 +94,24 @@ extension MastodonPickServerViewController {
|
|||
navigationItem.rightBarButtonItem?.menu = UIMenu(title: "Debug Tool", image: nil, identifier: nil, options: [], children: children)
|
||||
#endif
|
||||
|
||||
view.addSubview(nextStepButton)
|
||||
nextStepButtonBottomLayoutConstraint = view.bottomAnchor.constraint(equalTo: nextStepButton.bottomAnchor, constant: 0).priority(.defaultHigh)
|
||||
buttonContainer.translatesAutoresizingMaskIntoConstraints = false
|
||||
buttonContainer.preservesSuperviewLayoutMargins = true
|
||||
view.addSubview(buttonContainer)
|
||||
buttonContainerBottomLayoutConstraint = view.bottomAnchor.constraint(equalTo: buttonContainer.bottomAnchor, constant: 0).priority(.defaultHigh)
|
||||
NSLayoutConstraint.activate([
|
||||
nextStepButton.leadingAnchor.constraint(equalTo: view.readableContentGuide.leadingAnchor, constant: MastodonPickServerViewController.actionButtonMargin),
|
||||
view.readableContentGuide.trailingAnchor.constraint(equalTo: nextStepButton.trailingAnchor, constant: MastodonPickServerViewController.actionButtonMargin),
|
||||
buttonContainer.leadingAnchor.constraint(equalTo: view.leadingAnchor),
|
||||
buttonContainer.trailingAnchor.constraint(equalTo: view.trailingAnchor),
|
||||
view.safeAreaLayoutGuide.bottomAnchor.constraint(greaterThanOrEqualTo: buttonContainer.bottomAnchor, constant: WelcomeViewController.viewBottomPaddingHeight),
|
||||
buttonContainerBottomLayoutConstraint,
|
||||
])
|
||||
|
||||
view.addSubview(nextStepButton)
|
||||
NSLayoutConstraint.activate([
|
||||
nextStepButton.topAnchor.constraint(equalTo: buttonContainer.topAnchor),
|
||||
nextStepButton.leadingAnchor.constraint(equalTo: buttonContainer.layoutMarginsGuide.leadingAnchor),
|
||||
buttonContainer.layoutMarginsGuide.trailingAnchor.constraint(equalTo: nextStepButton.trailingAnchor),
|
||||
nextStepButton.bottomAnchor.constraint(equalTo: buttonContainer.bottomAnchor),
|
||||
nextStepButton.heightAnchor.constraint(equalToConstant: MastodonPickServerViewController.actionButtonHeight).priority(.defaultHigh),
|
||||
view.safeAreaLayoutGuide.bottomAnchor.constraint(greaterThanOrEqualTo: nextStepButton.bottomAnchor, constant: WelcomeViewController.viewBottomPaddingHeight),
|
||||
nextStepButtonBottomLayoutConstraint,
|
||||
])
|
||||
|
||||
// fix AutoLayout warning when observe before view appear
|
||||
|
@ -127,16 +142,18 @@ extension MastodonPickServerViewController {
|
|||
tableView.topAnchor.constraint(equalTo: view.topAnchor),
|
||||
tableView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
|
||||
tableView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
|
||||
nextStepButton.topAnchor.constraint(equalTo: tableView.bottomAnchor, constant: 7),
|
||||
buttonContainer.topAnchor.constraint(equalTo: tableView.bottomAnchor, constant: 7),
|
||||
])
|
||||
|
||||
emptyStateView.translatesAutoresizingMaskIntoConstraints = false
|
||||
view.addSubview(emptyStateView)
|
||||
emptyStateViewLeadingLayoutConstraint = emptyStateView.leadingAnchor.constraint(equalTo: tableView.leadingAnchor)
|
||||
emptyStateViewTrailingLayoutConstraint = tableView.trailingAnchor.constraint(equalTo: emptyStateView.trailingAnchor)
|
||||
NSLayoutConstraint.activate([
|
||||
emptyStateView.topAnchor.constraint(equalTo: view.topAnchor),
|
||||
emptyStateView.leadingAnchor.constraint(equalTo: tableView.readableContentGuide.leadingAnchor),
|
||||
emptyStateView.trailingAnchor.constraint(equalTo: tableView.readableContentGuide.trailingAnchor),
|
||||
nextStepButton.topAnchor.constraint(equalTo: emptyStateView.bottomAnchor, constant: 21),
|
||||
emptyStateViewLeadingLayoutConstraint,
|
||||
emptyStateViewTrailingLayoutConstraint,
|
||||
buttonContainer.topAnchor.constraint(equalTo: emptyStateView.bottomAnchor, constant: 21),
|
||||
])
|
||||
view.sendSubviewToBack(emptyStateView)
|
||||
|
||||
|
@ -154,18 +171,18 @@ extension MastodonPickServerViewController {
|
|||
|
||||
// guard external keyboard connected
|
||||
guard isShow, state == .dock, GCKeyboard.coalesced != nil else {
|
||||
self.nextStepButtonBottomLayoutConstraint.constant = WelcomeViewController.viewBottomPaddingHeight
|
||||
self.buttonContainerBottomLayoutConstraint.constant = WelcomeViewController.viewBottomPaddingHeight
|
||||
return
|
||||
}
|
||||
|
||||
let externalKeyboardToolbarHeight = self.view.frame.maxY - endFrame.minY
|
||||
guard externalKeyboardToolbarHeight > 0 else {
|
||||
self.nextStepButtonBottomLayoutConstraint.constant = WelcomeViewController.viewBottomPaddingHeight
|
||||
self.buttonContainerBottomLayoutConstraint.constant = WelcomeViewController.viewBottomPaddingHeight
|
||||
return
|
||||
}
|
||||
|
||||
UIView.animate(withDuration: 0.3) {
|
||||
self.nextStepButtonBottomLayoutConstraint.constant = externalKeyboardToolbarHeight + 16
|
||||
self.buttonContainerBottomLayoutConstraint.constant = externalKeyboardToolbarHeight + 16
|
||||
self.view.layoutIfNeeded()
|
||||
}
|
||||
}
|
||||
|
@ -274,9 +291,34 @@ extension MastodonPickServerViewController {
|
|||
viewModel.viewWillAppear.send()
|
||||
}
|
||||
|
||||
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
|
||||
super.traitCollectionDidChange(previousTraitCollection)
|
||||
|
||||
setupNavigationBarAppearance()
|
||||
updateEmptyStateViewLayout()
|
||||
configureTitleLabel()
|
||||
configureMargin()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension MastodonPickServerViewController {
|
||||
private func configureTitleLabel() {
|
||||
guard UIDevice.current.userInterfaceIdiom == .pad else {
|
||||
return
|
||||
}
|
||||
|
||||
switch traitCollection.horizontalSizeClass {
|
||||
case .regular:
|
||||
navigationItem.largeTitleDisplayMode = .always
|
||||
navigationItem.title = L10n.Scene.ServerPicker.title.replacingOccurrences(of: "\n", with: " ")
|
||||
default:
|
||||
navigationItem.largeTitleDisplayMode = .never
|
||||
navigationItem.title = nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension MastodonPickServerViewController {
|
||||
|
||||
@objc
|
||||
|
@ -426,43 +468,6 @@ extension MastodonPickServerViewController: UITableViewDelegate {
|
|||
}
|
||||
}
|
||||
|
||||
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
|
||||
let headerView = UIView()
|
||||
headerView.backgroundColor = Asset.Theme.Mastodon.systemGroupedBackground.color
|
||||
return headerView
|
||||
}
|
||||
|
||||
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
|
||||
guard let diffableDataSource = viewModel.diffableDataSource else {
|
||||
return .leastNonzeroMagnitude
|
||||
}
|
||||
let sections = diffableDataSource.snapshot().sectionIdentifiers
|
||||
let section = sections[section]
|
||||
switch section {
|
||||
case .header:
|
||||
return 20
|
||||
case .category:
|
||||
// Since category view has a blur shadow effect, its height need to be large than the actual height,
|
||||
// Thus we reduce the section header's height by 10, and make the category cell height 60+20(10 inset for top and bottom)
|
||||
return 10
|
||||
case .search:
|
||||
// Same reason as above
|
||||
return 10
|
||||
case .servers:
|
||||
return .leastNonzeroMagnitude
|
||||
}
|
||||
}
|
||||
|
||||
func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
|
||||
let footerView = UIView()
|
||||
footerView.backgroundColor = .yellow
|
||||
return footerView
|
||||
}
|
||||
|
||||
func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
|
||||
return .leastNonzeroMagnitude
|
||||
}
|
||||
|
||||
func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath? {
|
||||
guard let diffableDataSource = viewModel.diffableDataSource else { return nil }
|
||||
guard let item = diffableDataSource.itemIdentifier(for: indexPath) else { return nil }
|
||||
|
@ -521,6 +526,26 @@ extension MastodonPickServerViewController {
|
|||
let rectInTableView = tableView.rectForRow(at: indexPath)
|
||||
|
||||
emptyStateView.topPaddingViewTopLayoutConstraint.constant = rectInTableView.maxY
|
||||
|
||||
switch traitCollection.horizontalSizeClass {
|
||||
case .regular:
|
||||
emptyStateViewLeadingLayoutConstraint.constant = MastodonPickServerViewController.viewEdgeMargin
|
||||
emptyStateViewTrailingLayoutConstraint.constant = MastodonPickServerViewController.viewEdgeMargin
|
||||
default:
|
||||
let margin = tableView.layoutMarginsGuide.layoutFrame.origin.x
|
||||
emptyStateViewLeadingLayoutConstraint.constant = margin
|
||||
emptyStateViewTrailingLayoutConstraint.constant = margin
|
||||
}
|
||||
}
|
||||
|
||||
private func configureMargin() {
|
||||
switch traitCollection.horizontalSizeClass {
|
||||
case .regular:
|
||||
let margin = MastodonPickServerViewController.viewEdgeMargin
|
||||
buttonContainer.layoutMargins = UIEdgeInsets(top: 0, left: margin, bottom: 0, right: margin)
|
||||
default:
|
||||
buttonContainer.layoutMargins = .zero
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -56,12 +56,13 @@ extension PickServerCategoriesCell {
|
|||
private func _init() {
|
||||
selectionStyle = .none
|
||||
backgroundColor = Asset.Theme.Mastodon.systemGroupedBackground.color
|
||||
configureMargin()
|
||||
|
||||
metricView.translatesAutoresizingMaskIntoConstraints = false
|
||||
contentView.addSubview(metricView)
|
||||
NSLayoutConstraint.activate([
|
||||
metricView.leadingAnchor.constraint(equalTo: contentView.readableContentGuide.leadingAnchor),
|
||||
metricView.trailingAnchor.constraint(equalTo: contentView.readableContentGuide.trailingAnchor),
|
||||
metricView.leadingAnchor.constraint(equalTo: contentView.layoutMarginsGuide.leadingAnchor),
|
||||
metricView.trailingAnchor.constraint(equalTo: contentView.layoutMarginsGuide.trailingAnchor),
|
||||
metricView.topAnchor.constraint(equalTo: contentView.topAnchor),
|
||||
metricView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor),
|
||||
metricView.heightAnchor.constraint(equalToConstant: 80).priority(.defaultHigh),
|
||||
|
@ -71,14 +72,20 @@ extension PickServerCategoriesCell {
|
|||
NSLayoutConstraint.activate([
|
||||
collectionView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor),
|
||||
collectionView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor),
|
||||
collectionView.topAnchor.constraint(equalTo: contentView.topAnchor),
|
||||
collectionView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor),
|
||||
collectionView.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 10),
|
||||
contentView.bottomAnchor.constraint(equalTo: collectionView.bottomAnchor, constant: 20),
|
||||
collectionView.heightAnchor.constraint(equalToConstant: 80).priority(.defaultHigh),
|
||||
])
|
||||
|
||||
collectionView.delegate = self
|
||||
}
|
||||
|
||||
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
|
||||
super.traitCollectionDidChange(previousTraitCollection)
|
||||
|
||||
configureMargin()
|
||||
}
|
||||
|
||||
override func layoutSubviews() {
|
||||
super.layoutSubviews()
|
||||
|
||||
|
@ -87,6 +94,18 @@ extension PickServerCategoriesCell {
|
|||
|
||||
}
|
||||
|
||||
extension PickServerCategoriesCell {
|
||||
private func configureMargin() {
|
||||
switch traitCollection.horizontalSizeClass {
|
||||
case .regular:
|
||||
let margin = MastodonPickServerViewController.viewEdgeMargin
|
||||
contentView.layoutMargins = UIEdgeInsets(top: 0, left: margin, bottom: 0, right: margin)
|
||||
default:
|
||||
contentView.layoutMargins = .zero
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - UICollectionViewDelegateFlowLayout
|
||||
extension PickServerCategoriesCell: UICollectionViewDelegateFlowLayout {
|
||||
|
||||
|
|
|
@ -198,6 +198,7 @@ extension PickServerCell {
|
|||
private func _init() {
|
||||
selectionStyle = .none
|
||||
backgroundColor = .clear
|
||||
configureMargin()
|
||||
|
||||
contentView.addSubview(containerView)
|
||||
containerView.addSubview(domainLabel)
|
||||
|
@ -229,8 +230,8 @@ extension PickServerCell {
|
|||
NSLayoutConstraint.activate([
|
||||
// Set background view
|
||||
containerView.topAnchor.constraint(equalTo: contentView.topAnchor),
|
||||
containerView.leadingAnchor.constraint(equalTo: contentView.readableContentGuide.leadingAnchor),
|
||||
contentView.readableContentGuide.trailingAnchor.constraint(equalTo: containerView.trailingAnchor),
|
||||
containerView.leadingAnchor.constraint(equalTo: contentView.layoutMarginsGuide.leadingAnchor),
|
||||
contentView.layoutMarginsGuide.trailingAnchor.constraint(equalTo: containerView.trailingAnchor),
|
||||
contentView.bottomAnchor.constraint(equalTo: containerView.bottomAnchor),
|
||||
|
||||
// Set bottom separator
|
||||
|
@ -291,6 +292,12 @@ extension PickServerCell {
|
|||
expandButton.addTarget(self, action: #selector(expandButtonDidPressed(_:)), for: .touchUpInside)
|
||||
}
|
||||
|
||||
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
|
||||
super.traitCollectionDidChange(previousTraitCollection)
|
||||
|
||||
configureMargin()
|
||||
}
|
||||
|
||||
private func makeVerticalInfoStackView(arrangedView: UIView...) -> UIStackView {
|
||||
let stackView = UIStackView()
|
||||
stackView.translatesAutoresizingMaskIntoConstraints = false
|
||||
|
@ -318,6 +325,18 @@ extension PickServerCell {
|
|||
}
|
||||
}
|
||||
|
||||
extension PickServerCell {
|
||||
private func configureMargin() {
|
||||
switch traitCollection.horizontalSizeClass {
|
||||
case .regular:
|
||||
let margin = MastodonPickServerViewController.viewEdgeMargin
|
||||
contentView.layoutMargins = UIEdgeInsets(top: 0, left: margin, bottom: 0, right: margin)
|
||||
default:
|
||||
contentView.layoutMargins = .zero
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension PickServerCell {
|
||||
|
||||
enum ExpandMode {
|
||||
|
|
|
@ -37,14 +37,16 @@ final class PickServerLoaderTableViewCell: TimelineLoaderTableViewCell {
|
|||
override func _init() {
|
||||
super._init()
|
||||
|
||||
configureMargin()
|
||||
|
||||
contentView.addSubview(containerView)
|
||||
contentView.addSubview(seperator)
|
||||
|
||||
NSLayoutConstraint.activate([
|
||||
// Set background view
|
||||
containerView.topAnchor.constraint(equalTo: contentView.topAnchor),
|
||||
containerView.leadingAnchor.constraint(equalTo: contentView.readableContentGuide.leadingAnchor),
|
||||
contentView.readableContentGuide.trailingAnchor.constraint(equalTo: containerView.trailingAnchor),
|
||||
containerView.leadingAnchor.constraint(equalTo: contentView.layoutMarginsGuide.leadingAnchor),
|
||||
contentView.layoutMarginsGuide.trailingAnchor.constraint(equalTo: containerView.trailingAnchor),
|
||||
contentView.bottomAnchor.constraint(equalTo: containerView.bottomAnchor, constant: 1),
|
||||
|
||||
// Set bottom separator
|
||||
|
@ -67,6 +69,24 @@ final class PickServerLoaderTableViewCell: TimelineLoaderTableViewCell {
|
|||
activityIndicatorView.isHidden = false
|
||||
startAnimating()
|
||||
}
|
||||
|
||||
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
|
||||
super.traitCollectionDidChange(previousTraitCollection)
|
||||
|
||||
configureMargin()
|
||||
}
|
||||
}
|
||||
|
||||
extension PickServerLoaderTableViewCell {
|
||||
private func configureMargin() {
|
||||
switch traitCollection.horizontalSizeClass {
|
||||
case .regular:
|
||||
let margin = MastodonPickServerViewController.viewEdgeMargin
|
||||
contentView.layoutMargins = UIEdgeInsets(top: 0, left: margin, bottom: 0, right: margin)
|
||||
default:
|
||||
contentView.layoutMargins = .zero
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if canImport(SwiftUI) && DEBUG
|
||||
|
|
|
@ -109,6 +109,7 @@ extension PickServerSearchCell {
|
|||
private func _init() {
|
||||
selectionStyle = .none
|
||||
backgroundColor = Asset.Theme.Mastodon.systemGroupedBackground.color
|
||||
configureMargin()
|
||||
|
||||
searchTextField.addTarget(self, action: #selector(textFieldDidChange(_:)), for: .editingChanged)
|
||||
searchTextField.delegate = self
|
||||
|
@ -118,9 +119,9 @@ extension PickServerSearchCell {
|
|||
contentView.addSubview(searchTextField)
|
||||
|
||||
NSLayoutConstraint.activate([
|
||||
bgView.leadingAnchor.constraint(equalTo: contentView.readableContentGuide.leadingAnchor),
|
||||
bgView.leadingAnchor.constraint(equalTo: contentView.layoutMarginsGuide.leadingAnchor),
|
||||
bgView.topAnchor.constraint(equalTo: contentView.topAnchor),
|
||||
bgView.trailingAnchor.constraint(equalTo: contentView.readableContentGuide.trailingAnchor),
|
||||
bgView.trailingAnchor.constraint(equalTo: contentView.layoutMarginsGuide.trailingAnchor),
|
||||
bgView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor),
|
||||
|
||||
textFieldBgView.leadingAnchor.constraint(equalTo: bgView.leadingAnchor, constant: 14),
|
||||
|
@ -134,6 +135,24 @@ extension PickServerSearchCell {
|
|||
textFieldBgView.bottomAnchor.constraint(equalTo: searchTextField.bottomAnchor, constant: 4),
|
||||
])
|
||||
}
|
||||
|
||||
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
|
||||
super.traitCollectionDidChange(previousTraitCollection)
|
||||
|
||||
configureMargin()
|
||||
}
|
||||
}
|
||||
|
||||
extension PickServerSearchCell {
|
||||
private func configureMargin() {
|
||||
switch traitCollection.horizontalSizeClass {
|
||||
case .regular:
|
||||
let margin = MastodonPickServerViewController.viewEdgeMargin
|
||||
contentView.layoutMargins = UIEdgeInsets(top: 0, left: margin, bottom: 0, right: margin)
|
||||
default:
|
||||
contentView.layoutMargins = .zero
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension PickServerSearchCell {
|
||||
|
|
|
@ -20,6 +20,8 @@ final class PickServerTitleCell: UITableViewCell {
|
|||
return label
|
||||
}()
|
||||
|
||||
var containerHeightLayoutConstraint: NSLayoutConstraint!
|
||||
|
||||
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
|
||||
super.init(style: style, reuseIdentifier: reuseIdentifier)
|
||||
_init()
|
||||
|
@ -36,13 +38,45 @@ extension PickServerTitleCell {
|
|||
private func _init() {
|
||||
selectionStyle = .none
|
||||
backgroundColor = Asset.Theme.Mastodon.systemGroupedBackground.color
|
||||
|
||||
contentView.addSubview(titleLabel)
|
||||
|
||||
let container = UIStackView()
|
||||
container.axis = .vertical
|
||||
container.translatesAutoresizingMaskIntoConstraints = false
|
||||
containerHeightLayoutConstraint = container.heightAnchor.constraint(equalToConstant: .leastNonzeroMagnitude)
|
||||
contentView.addSubview(container)
|
||||
NSLayoutConstraint.activate([
|
||||
titleLabel.leadingAnchor.constraint(equalTo: contentView.readableContentGuide.leadingAnchor),
|
||||
contentView.readableContentGuide.trailingAnchor.constraint(equalTo: titleLabel.trailingAnchor),
|
||||
titleLabel.topAnchor.constraint(equalTo: contentView.topAnchor),
|
||||
titleLabel.bottomAnchor.constraint(equalTo: contentView.bottomAnchor),
|
||||
container.topAnchor.constraint(equalTo: contentView.topAnchor),
|
||||
container.leadingAnchor.constraint(equalTo: contentView.readableContentGuide.leadingAnchor),
|
||||
container.trailingAnchor.constraint(equalTo: contentView.readableContentGuide.trailingAnchor),
|
||||
container.bottomAnchor.constraint(equalTo: contentView.bottomAnchor),
|
||||
])
|
||||
|
||||
container.addArrangedSubview(titleLabel)
|
||||
|
||||
configureTitleLabelDisplay()
|
||||
}
|
||||
|
||||
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
|
||||
super.traitCollectionDidChange(previousTraitCollection)
|
||||
|
||||
configureTitleLabelDisplay()
|
||||
}
|
||||
}
|
||||
|
||||
extension PickServerTitleCell {
|
||||
private func configureTitleLabelDisplay() {
|
||||
guard traitCollection.userInterfaceIdiom == .pad else {
|
||||
titleLabel.isHidden = false
|
||||
return
|
||||
}
|
||||
|
||||
switch traitCollection.horizontalSizeClass {
|
||||
case .regular:
|
||||
titleLabel.isHidden = true
|
||||
containerHeightLayoutConstraint.isActive = true
|
||||
default:
|
||||
titleLabel.isHidden = false
|
||||
containerHeightLayoutConstraint.isActive = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -61,6 +61,8 @@ final class MastodonRegisterViewController: UIViewController, NeedsDependency, O
|
|||
return scrollview
|
||||
}()
|
||||
|
||||
let stackView = UIStackView()
|
||||
|
||||
let largeTitleLabel: UILabel = {
|
||||
let label = UILabel()
|
||||
label.font = UIFontMetrics(forTextStyle: .largeTitle).scaledFont(for: .systemFont(ofSize: 34, weight: .bold))
|
||||
|
@ -287,7 +289,11 @@ extension MastodonRegisterViewController {
|
|||
super.viewDidLoad()
|
||||
|
||||
setupOnboardingAppearance()
|
||||
defer { setupNavigationBarBackgroundView() }
|
||||
configureTitleLabel()
|
||||
defer {
|
||||
setupNavigationBarBackgroundView()
|
||||
configureFormLayout()
|
||||
}
|
||||
|
||||
avatarButton.menu = createMediaContextMenu()
|
||||
avatarButton.showsMenuAsPrimaryAction = true
|
||||
|
@ -307,7 +313,6 @@ extension MastodonRegisterViewController {
|
|||
tapGestureRecognizer.addTarget(self, action: #selector(tapGestureRecognizerHandler))
|
||||
|
||||
// stackview
|
||||
let stackView = UIStackView()
|
||||
stackView.axis = .vertical
|
||||
stackView.distribution = .fill
|
||||
stackView.spacing = 40
|
||||
|
@ -315,17 +320,24 @@ extension MastodonRegisterViewController {
|
|||
stackView.isLayoutMarginsRelativeArrangement = true
|
||||
stackView.addArrangedSubview(largeTitleLabel)
|
||||
stackView.addArrangedSubview(avatarView)
|
||||
stackView.addArrangedSubview(usernameTextField)
|
||||
stackView.addArrangedSubview(displayNameTextField)
|
||||
stackView.addArrangedSubview(emailTextField)
|
||||
stackView.addArrangedSubview(passwordTextField)
|
||||
stackView.addArrangedSubview(passwordCheckLabel)
|
||||
|
||||
let formTableStackView = UIStackView()
|
||||
stackView.addArrangedSubview(formTableStackView)
|
||||
formTableStackView.axis = .vertical
|
||||
formTableStackView.distribution = .fill
|
||||
formTableStackView.spacing = 40
|
||||
|
||||
formTableStackView.addArrangedSubview(usernameTextField)
|
||||
formTableStackView.addArrangedSubview(displayNameTextField)
|
||||
formTableStackView.addArrangedSubview(emailTextField)
|
||||
formTableStackView.addArrangedSubview(passwordTextField)
|
||||
formTableStackView.addArrangedSubview(passwordCheckLabel)
|
||||
if viewModel.approvalRequired {
|
||||
stackView.addArrangedSubview(reasonTextField)
|
||||
formTableStackView.addArrangedSubview(reasonTextField)
|
||||
}
|
||||
|
||||
usernameErrorPromptLabel.translatesAutoresizingMaskIntoConstraints = false
|
||||
stackView.addSubview(usernameErrorPromptLabel)
|
||||
formTableStackView.addSubview(usernameErrorPromptLabel)
|
||||
NSLayoutConstraint.activate([
|
||||
usernameErrorPromptLabel.topAnchor.constraint(equalTo: usernameTextField.bottomAnchor, constant: 6),
|
||||
usernameErrorPromptLabel.leadingAnchor.constraint(equalTo: usernameTextField.leadingAnchor),
|
||||
|
@ -333,7 +345,7 @@ extension MastodonRegisterViewController {
|
|||
])
|
||||
|
||||
emailErrorPromptLabel.translatesAutoresizingMaskIntoConstraints = false
|
||||
stackView.addSubview(emailErrorPromptLabel)
|
||||
formTableStackView.addSubview(emailErrorPromptLabel)
|
||||
NSLayoutConstraint.activate([
|
||||
emailErrorPromptLabel.topAnchor.constraint(equalTo: emailTextField.bottomAnchor, constant: 6),
|
||||
emailErrorPromptLabel.leadingAnchor.constraint(equalTo: emailTextField.leadingAnchor),
|
||||
|
@ -341,7 +353,7 @@ extension MastodonRegisterViewController {
|
|||
])
|
||||
|
||||
passwordErrorPromptLabel.translatesAutoresizingMaskIntoConstraints = false
|
||||
stackView.addSubview(passwordErrorPromptLabel)
|
||||
formTableStackView.addSubview(passwordErrorPromptLabel)
|
||||
NSLayoutConstraint.activate([
|
||||
passwordErrorPromptLabel.topAnchor.constraint(equalTo: passwordCheckLabel.bottomAnchor, constant: 2),
|
||||
passwordErrorPromptLabel.leadingAnchor.constraint(equalTo: passwordTextField.leadingAnchor),
|
||||
|
@ -373,12 +385,14 @@ extension MastodonRegisterViewController {
|
|||
avatarView.translatesAutoresizingMaskIntoConstraints = false
|
||||
avatarView.addSubview(avatarButton)
|
||||
NSLayoutConstraint.activate([
|
||||
avatarView.heightAnchor.constraint(equalToConstant: 90).priority(.defaultHigh),
|
||||
avatarView.heightAnchor.constraint(equalToConstant: 92).priority(.required - 1),
|
||||
])
|
||||
avatarButton.translatesAutoresizingMaskIntoConstraints = false
|
||||
NSLayoutConstraint.activate([
|
||||
avatarButton.heightAnchor.constraint(equalToConstant: 92).priority(.defaultHigh),
|
||||
avatarButton.widthAnchor.constraint(equalToConstant: 92).priority(.defaultHigh),
|
||||
avatarButton.heightAnchor.constraint(equalToConstant: 92).priority(.required - 1),
|
||||
avatarButton.widthAnchor.constraint(equalToConstant: 92).priority(.required - 1),
|
||||
avatarButton.leadingAnchor.constraint(greaterThanOrEqualTo: avatarView.leadingAnchor).priority(.required - 1),
|
||||
avatarView.trailingAnchor.constraint(greaterThanOrEqualTo: avatarButton.trailingAnchor).priority(.required - 1),
|
||||
avatarButton.centerXAnchor.constraint(equalTo: avatarView.centerXAnchor),
|
||||
avatarButton.centerYAnchor.constraint(equalTo: avatarView.centerYAnchor),
|
||||
])
|
||||
|
@ -392,15 +406,15 @@ extension MastodonRegisterViewController {
|
|||
|
||||
// textfield
|
||||
NSLayoutConstraint.activate([
|
||||
usernameTextField.heightAnchor.constraint(equalToConstant: 50).priority(.defaultHigh),
|
||||
displayNameTextField.heightAnchor.constraint(equalToConstant: 50).priority(.defaultHigh),
|
||||
emailTextField.heightAnchor.constraint(equalToConstant: 50).priority(.defaultHigh),
|
||||
passwordTextField.heightAnchor.constraint(equalToConstant: 50).priority(.defaultHigh),
|
||||
usernameTextField.heightAnchor.constraint(equalToConstant: 50).priority(.required - 1),
|
||||
displayNameTextField.heightAnchor.constraint(equalToConstant: 50).priority(.required - 1),
|
||||
emailTextField.heightAnchor.constraint(equalToConstant: 50).priority(.required - 1),
|
||||
passwordTextField.heightAnchor.constraint(equalToConstant: 50).priority(.required - 1),
|
||||
])
|
||||
|
||||
// password
|
||||
stackView.setCustomSpacing(6, after: passwordTextField)
|
||||
stackView.setCustomSpacing(32, after: passwordCheckLabel)
|
||||
formTableStackView.setCustomSpacing(6, after: passwordTextField)
|
||||
formTableStackView.setCustomSpacing(32, after: passwordCheckLabel)
|
||||
|
||||
// return
|
||||
if viewModel.approvalRequired {
|
||||
|
@ -410,16 +424,22 @@ extension MastodonRegisterViewController {
|
|||
}
|
||||
|
||||
// button
|
||||
stackView.addArrangedSubview(buttonContainer)
|
||||
formTableStackView.addArrangedSubview(buttonContainer)
|
||||
signUpButton.translatesAutoresizingMaskIntoConstraints = false
|
||||
buttonContainer.addSubview(signUpButton)
|
||||
NSLayoutConstraint.activate([
|
||||
signUpButton.topAnchor.constraint(equalTo: buttonContainer.topAnchor),
|
||||
signUpButton.leadingAnchor.constraint(equalTo: buttonContainer.leadingAnchor, constant: MastodonRegisterViewController.actionButtonMargin),
|
||||
buttonContainer.trailingAnchor.constraint(equalTo: signUpButton.trailingAnchor, constant: MastodonRegisterViewController.actionButtonMargin),
|
||||
signUpButton.leadingAnchor.constraint(equalTo: buttonContainer.leadingAnchor),
|
||||
buttonContainer.trailingAnchor.constraint(equalTo: signUpButton.trailingAnchor),
|
||||
buttonContainer.bottomAnchor.constraint(equalTo: signUpButton.bottomAnchor),
|
||||
signUpButton.heightAnchor.constraint(equalToConstant: MastodonRegisterViewController.actionButtonHeight).priority(.defaultHigh),
|
||||
signUpButton.heightAnchor.constraint(equalToConstant: MastodonRegisterViewController.actionButtonHeight).priority(.required - 1),
|
||||
buttonContainer.heightAnchor.constraint(equalToConstant: MastodonRegisterViewController.actionButtonHeight).priority(.required - 1),
|
||||
])
|
||||
signUpButton.setContentHuggingPriority(.defaultLow, for: .horizontal)
|
||||
signUpButton.setContentHuggingPriority(.defaultLow, for: .vertical)
|
||||
signUpButton.setContentCompressionResistancePriority(.required - 1, for: .vertical)
|
||||
signUpButton.setContentCompressionResistancePriority(.required - 1, for: .horizontal)
|
||||
buttonContainer.setContentCompressionResistancePriority(.required - 1, for: .vertical)
|
||||
|
||||
Publishers.CombineLatest(
|
||||
KeyboardResponderService.shared.state.eraseToAnyPublisher(),
|
||||
|
@ -645,6 +665,12 @@ extension MastodonRegisterViewController {
|
|||
plusIconImageView.layer.masksToBounds = true
|
||||
}
|
||||
|
||||
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
|
||||
super.traitCollectionDidChange(previousTraitCollection)
|
||||
|
||||
configureTitleLabel()
|
||||
configureFormLayout()
|
||||
}
|
||||
}
|
||||
|
||||
extension MastodonRegisterViewController: UITextFieldDelegate {
|
||||
|
@ -714,7 +740,7 @@ extension MastodonRegisterViewController: UITextFieldDelegate {
|
|||
textField.layer.shadowRadius = 2.0
|
||||
textField.layer.shadowOffset = CGSize.zero
|
||||
textField.layer.shadowColor = color.cgColor
|
||||
textField.layer.shadowPath = UIBezierPath(roundedRect: textField.bounds, byRoundingCorners: .allCorners, cornerRadii: CGSize(width: 2.0, height: 2.0)).cgPath
|
||||
// textField.layer.shadowPath = UIBezierPath(roundedRect: textField.bounds, byRoundingCorners: .allCorners, cornerRadii: CGSize(width: 2.0, height: 2.0)).cgPath
|
||||
}
|
||||
|
||||
private func setTextFieldValidAppearance(_ textField: UITextField, validateState: MastodonRegisterViewModel.ValidateState) {
|
||||
|
@ -729,6 +755,36 @@ extension MastodonRegisterViewController: UITextFieldDelegate {
|
|||
}
|
||||
}
|
||||
|
||||
extension MastodonRegisterViewController {
|
||||
private func configureTitleLabel() {
|
||||
switch traitCollection.horizontalSizeClass {
|
||||
case .regular:
|
||||
navigationItem.largeTitleDisplayMode = .always
|
||||
navigationItem.title = L10n.Scene.ServerPicker.title.replacingOccurrences(of: "\n", with: " ")
|
||||
largeTitleLabel.isHidden = true
|
||||
default:
|
||||
navigationItem.largeTitleDisplayMode = .never
|
||||
navigationItem.title = nil
|
||||
largeTitleLabel.isHidden = false
|
||||
}
|
||||
}
|
||||
|
||||
private func configureFormLayout() {
|
||||
switch traitCollection.horizontalSizeClass {
|
||||
case .regular:
|
||||
stackView.axis = .horizontal
|
||||
stackView.distribution = .fillProportionally
|
||||
default:
|
||||
stackView.axis = .vertical
|
||||
stackView.distribution = .fill
|
||||
}
|
||||
}
|
||||
|
||||
private func configureMargin() {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
extension MastodonRegisterViewController {
|
||||
@objc private func tapGestureRecognizerHandler(_ sender: UITapGestureRecognizer) {
|
||||
view.endEditing(true)
|
||||
|
|
|
@ -21,6 +21,8 @@ final class MastodonServerRulesViewController: UIViewController, NeedsDependency
|
|||
|
||||
var viewModel: MastodonServerRulesViewModel!
|
||||
|
||||
let stackView = UIStackView()
|
||||
|
||||
let largeTitleLabel: UILabel = {
|
||||
let label = UILabel()
|
||||
label.font = UIFontMetrics(forTextStyle: .largeTitle).scaledFont(for: .systemFont(ofSize: 34, weight: .bold))
|
||||
|
@ -96,6 +98,8 @@ extension MastodonServerRulesViewController {
|
|||
super.viewDidLoad()
|
||||
|
||||
setupOnboardingAppearance()
|
||||
configureTitleLabel()
|
||||
configureMargin()
|
||||
configTextView()
|
||||
|
||||
defer { setupNavigationBarBackgroundView() }
|
||||
|
@ -116,8 +120,8 @@ extension MastodonServerRulesViewController {
|
|||
bottomContainerView.addSubview(confirmButton)
|
||||
NSLayoutConstraint.activate([
|
||||
bottomContainerView.layoutMarginsGuide.bottomAnchor.constraint(equalTo: confirmButton.bottomAnchor, constant: MastodonServerRulesViewController.viewBottomPaddingHeight),
|
||||
confirmButton.leadingAnchor.constraint(equalTo: bottomContainerView.readableContentGuide.leadingAnchor, constant: MastodonServerRulesViewController.actionButtonMargin),
|
||||
bottomContainerView.readableContentGuide.trailingAnchor.constraint(equalTo: confirmButton.trailingAnchor, constant: MastodonServerRulesViewController.actionButtonMargin),
|
||||
confirmButton.leadingAnchor.constraint(equalTo: bottomContainerView.layoutMarginsGuide.leadingAnchor),
|
||||
bottomContainerView.layoutMarginsGuide.trailingAnchor.constraint(equalTo: confirmButton.trailingAnchor),
|
||||
confirmButton.heightAnchor.constraint(equalToConstant: MastodonServerRulesViewController.actionButtonHeight).priority(.defaultHigh),
|
||||
])
|
||||
|
||||
|
@ -125,8 +129,8 @@ extension MastodonServerRulesViewController {
|
|||
bottomContainerView.addSubview(bottomPromptMetaText.textView)
|
||||
NSLayoutConstraint.activate([
|
||||
bottomPromptMetaText.textView.frameLayoutGuide.topAnchor.constraint(equalTo: bottomContainerView.topAnchor, constant: 20),
|
||||
bottomPromptMetaText.textView.frameLayoutGuide.leadingAnchor.constraint(equalTo: bottomContainerView.readableContentGuide.leadingAnchor),
|
||||
bottomPromptMetaText.textView.frameLayoutGuide.trailingAnchor.constraint(equalTo: bottomContainerView.readableContentGuide.trailingAnchor),
|
||||
bottomPromptMetaText.textView.frameLayoutGuide.leadingAnchor.constraint(equalTo: bottomContainerView.layoutMarginsGuide.leadingAnchor),
|
||||
bottomPromptMetaText.textView.frameLayoutGuide.trailingAnchor.constraint(equalTo: bottomContainerView.layoutMarginsGuide.trailingAnchor),
|
||||
confirmButton.topAnchor.constraint(equalTo: bottomPromptMetaText.textView.frameLayoutGuide.bottomAnchor, constant: 20),
|
||||
])
|
||||
|
||||
|
@ -140,10 +144,10 @@ extension MastodonServerRulesViewController {
|
|||
scrollView.frameLayoutGuide.widthAnchor.constraint(equalTo: scrollView.contentLayoutGuide.widthAnchor),
|
||||
])
|
||||
|
||||
let stackView = UIStackView()
|
||||
stackView.axis = .vertical
|
||||
stackView.distribution = .fill
|
||||
stackView.spacing = 10
|
||||
stackView.isLayoutMarginsRelativeArrangement = true
|
||||
stackView.layoutMargins = UIEdgeInsets(top: 20, left: 0, bottom: 20, right: 0)
|
||||
stackView.addArrangedSubview(largeTitleLabel)
|
||||
stackView.addArrangedSubview(subtitleLabel)
|
||||
|
@ -178,6 +182,46 @@ extension MastodonServerRulesViewController {
|
|||
updateScrollViewContentInset()
|
||||
}
|
||||
|
||||
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
|
||||
super.traitCollectionDidChange(previousTraitCollection)
|
||||
|
||||
setupNavigationBarAppearance()
|
||||
configureTitleLabel()
|
||||
configureMargin()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension MastodonServerRulesViewController {
|
||||
private func configureTitleLabel() {
|
||||
guard UIDevice.current.userInterfaceIdiom == .pad else {
|
||||
return
|
||||
}
|
||||
|
||||
switch traitCollection.horizontalSizeClass {
|
||||
case .regular:
|
||||
navigationItem.largeTitleDisplayMode = .always
|
||||
navigationItem.title = L10n.Scene.ServerRules.title.replacingOccurrences(of: "\n", with: " ")
|
||||
largeTitleLabel.isHidden = true
|
||||
default:
|
||||
navigationItem.leftBarButtonItem = nil
|
||||
navigationItem.largeTitleDisplayMode = .never
|
||||
navigationItem.title = nil
|
||||
largeTitleLabel.isHidden = false
|
||||
}
|
||||
}
|
||||
|
||||
private func configureMargin() {
|
||||
switch traitCollection.horizontalSizeClass {
|
||||
case .regular:
|
||||
let margin = MastodonPickServerViewController.viewEdgeMargin
|
||||
stackView.layoutMargins = UIEdgeInsets(top: 32, left: margin, bottom: 20, right: margin)
|
||||
bottomContainerView.layoutMargins = UIEdgeInsets(top: 0, left: margin, bottom: 0, right: margin)
|
||||
default:
|
||||
stackView.layoutMargins = UIEdgeInsets(top: 20, left: 0, bottom: 20, right: 0)
|
||||
bottomContainerView.layoutMargins = .zero
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension MastodonServerRulesViewController {
|
||||
|
|
|
@ -24,19 +24,38 @@ extension OnboardingViewControllerAppearance {
|
|||
|
||||
setupNavigationBarAppearance()
|
||||
|
||||
let backItem = UIBarButtonItem()
|
||||
backItem.title = L10n.Common.Controls.Actions.back
|
||||
let backItem = UIBarButtonItem(
|
||||
title: L10n.Common.Controls.Actions.back,
|
||||
style: .plain,
|
||||
target: nil,
|
||||
action: nil
|
||||
)
|
||||
navigationItem.backBarButtonItem = backItem
|
||||
}
|
||||
|
||||
func setupNavigationBarAppearance() {
|
||||
// use TransparentBackground so view push / dismiss will be more visual nature
|
||||
// please add opaque background for status bar manually if needs
|
||||
let barAppearance = UINavigationBarAppearance()
|
||||
barAppearance.configureWithTransparentBackground()
|
||||
navigationController?.navigationBar.standardAppearance = barAppearance
|
||||
navigationController?.navigationBar.compactAppearance = barAppearance
|
||||
navigationController?.navigationBar.scrollEdgeAppearance = barAppearance
|
||||
|
||||
switch traitCollection.userInterfaceIdiom {
|
||||
case .pad:
|
||||
if traitCollection.horizontalSizeClass == .regular {
|
||||
// do nothing
|
||||
} else {
|
||||
fallthrough
|
||||
}
|
||||
default:
|
||||
let barAppearance = UINavigationBarAppearance()
|
||||
barAppearance.configureWithTransparentBackground()
|
||||
navigationItem.standardAppearance = barAppearance
|
||||
navigationItem.compactAppearance = barAppearance
|
||||
navigationItem.scrollEdgeAppearance = barAppearance
|
||||
if #available(iOS 15.0, *) {
|
||||
navigationItem.compactScrollEdgeAppearance = barAppearance
|
||||
} else {
|
||||
// Fallback on earlier versions
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func setupNavigationBarBackgroundView() {
|
||||
|
@ -57,3 +76,12 @@ extension OnboardingViewControllerAppearance {
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
extension OnboardingViewControllerAppearance {
|
||||
static var viewEdgeMargin: CGFloat {
|
||||
guard UIDevice.current.userInterfaceIdiom == .pad else { return .zero }
|
||||
|
||||
let shortEdgeWidth = min(UIScreen.main.bounds.height, UIScreen.main.bounds.width)
|
||||
return shortEdgeWidth * 0.17 // magic
|
||||
}
|
||||
}
|
||||
|
|
|
@ -75,6 +75,8 @@ extension WelcomeViewController {
|
|||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
|
||||
navigationController?.navigationBar.prefersLargeTitles = true
|
||||
navigationItem.largeTitleDisplayMode = .never
|
||||
view.overrideUserInterfaceStyle = .light
|
||||
|
||||
setupOnboardingAppearance()
|
||||
|
@ -235,7 +237,21 @@ extension WelcomeViewController {
|
|||
}
|
||||
|
||||
// MARK: - OnboardingViewControllerAppearance
|
||||
extension WelcomeViewController: OnboardingViewControllerAppearance { }
|
||||
extension WelcomeViewController: OnboardingViewControllerAppearance {
|
||||
func setupNavigationBarAppearance() {
|
||||
// always transparent
|
||||
let barAppearance = UINavigationBarAppearance()
|
||||
barAppearance.configureWithTransparentBackground()
|
||||
navigationItem.standardAppearance = barAppearance
|
||||
navigationItem.compactAppearance = barAppearance
|
||||
navigationItem.scrollEdgeAppearance = barAppearance
|
||||
if #available(iOS 15.0, *) {
|
||||
navigationItem.compactScrollEdgeAppearance = barAppearance
|
||||
} else {
|
||||
// Fallback on earlier versions
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - UIAdaptivePresentationControllerDelegate
|
||||
extension WelcomeViewController: UIAdaptivePresentationControllerDelegate {
|
||||
|
@ -245,7 +261,12 @@ extension WelcomeViewController: UIAdaptivePresentationControllerDelegate {
|
|||
// make underneath view controller alive to fix layout issue due to view life cycle
|
||||
return .fullScreen
|
||||
default:
|
||||
return .pageSheet
|
||||
switch traitCollection.horizontalSizeClass {
|
||||
case .regular:
|
||||
return .pageSheet
|
||||
default:
|
||||
return .fullScreen
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -317,7 +317,7 @@ extension MainTabBarController {
|
|||
|
||||
switch tab {
|
||||
case .me:
|
||||
coordinator.present(scene: .accountList, from: nil, transition: .panModal)
|
||||
coordinator.present(scene: .accountList, from: self, transition: .panModal)
|
||||
default:
|
||||
break
|
||||
}
|
||||
|
@ -353,7 +353,6 @@ extension MainTabBarController {
|
|||
self.avatarButton.setContentHuggingPriority(.required - 1, for: .vertical)
|
||||
self.avatarButton.isUserInteractionEnabled = false
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension MainTabBarController {
|
||||
|
|
|
@ -201,6 +201,12 @@ extension RootSplitViewController: UISplitViewControllerDelegate {
|
|||
displayModeForExpandingToProposedDisplayMode proposedDisplayMode: UISplitViewController.DisplayMode
|
||||
) -> UISplitViewController.DisplayMode {
|
||||
let compactNavigationController = mainTabBarController.selectedViewController as? UINavigationController
|
||||
|
||||
if let topMost = compactNavigationController?.topMost,
|
||||
topMost is AccountListViewController {
|
||||
topMost.dismiss(animated: false, completion: nil)
|
||||
}
|
||||
|
||||
let viewControllers = compactNavigationController?.popToRootViewController(animated: true) ?? []
|
||||
|
||||
var supplementaryViewControllers: [UIViewController] = []
|
||||
|
@ -219,6 +225,7 @@ extension RootSplitViewController: UISplitViewControllerDelegate {
|
|||
if let secondaryNavigationController = viewController(for: .secondary) as? UINavigationController {
|
||||
secondaryNavigationController.setViewControllers(secondaryNavigationController.viewControllers + secondaryViewControllers, animated: false)
|
||||
}
|
||||
|
||||
return proposedDisplayMode
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue