diff --git a/Mastodon.xcodeproj/xcuserdata/mainasuk.xcuserdatad/xcschemes/xcschememanagement.plist b/Mastodon.xcodeproj/xcuserdata/mainasuk.xcuserdatad/xcschemes/xcschememanagement.plist index 068a73491..e6093a218 100644 --- a/Mastodon.xcodeproj/xcuserdata/mainasuk.xcuserdatad/xcschemes/xcschememanagement.plist +++ b/Mastodon.xcodeproj/xcuserdata/mainasuk.xcuserdatad/xcschemes/xcschememanagement.plist @@ -7,12 +7,12 @@ AppShared.xcscheme_^#shared#^_ orderHint - 56 + 35 CoreDataStack.xcscheme_^#shared#^_ orderHint - 54 + 38 Mastodon - ASDK.xcscheme_^#shared#^_ @@ -97,7 +97,7 @@ MastodonIntent.xcscheme_^#shared#^_ orderHint - 51 + 36 MastodonIntents.xcscheme_^#shared#^_ @@ -117,7 +117,7 @@ ShareActionExtension.xcscheme_^#shared#^_ orderHint - 55 + 37 SuppressBuildableAutocreation diff --git a/Mastodon/Coordinator/SceneCoordinator.swift b/Mastodon/Coordinator/SceneCoordinator.swift index 83ae61a84..3178a2cb7 100644 --- a/Mastodon/Coordinator/SceneCoordinator.swift +++ b/Mastodon/Coordinator/SceneCoordinator.swift @@ -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 diff --git a/Mastodon/Scene/Onboarding/ConfirmEmail/MastodonConfirmEmailViewController.swift b/Mastodon/Scene/Onboarding/ConfirmEmail/MastodonConfirmEmailViewController.swift index 1abb35617..0718938f6 100644 --- a/Mastodon/Scene/Onboarding/ConfirmEmail/MastodonConfirmEmailViewController.swift +++ b/Mastodon/Scene/Onboarding/ConfirmEmail/MastodonConfirmEmailViewController.swift @@ -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 { diff --git a/Mastodon/Scene/Onboarding/PickServer/MastodonPickServerViewController.swift b/Mastodon/Scene/Onboarding/PickServer/MastodonPickServerViewController.swift index 3da704f0b..f3570c6c5 100644 --- a/Mastodon/Scene/Onboarding/PickServer/MastodonPickServerViewController.swift +++ b/Mastodon/Scene/Onboarding/PickServer/MastodonPickServerViewController.swift @@ -29,6 +29,8 @@ final class MastodonPickServerViewController: UIViewController, NeedsDependency private var expandServerDomainSet = Set() 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 + } } } diff --git a/Mastodon/Scene/Onboarding/PickServer/TableViewCell/PickServerCategoriesCell.swift b/Mastodon/Scene/Onboarding/PickServer/TableViewCell/PickServerCategoriesCell.swift index 8207ccdb9..659317752 100644 --- a/Mastodon/Scene/Onboarding/PickServer/TableViewCell/PickServerCategoriesCell.swift +++ b/Mastodon/Scene/Onboarding/PickServer/TableViewCell/PickServerCategoriesCell.swift @@ -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 { diff --git a/Mastodon/Scene/Onboarding/PickServer/TableViewCell/PickServerCell.swift b/Mastodon/Scene/Onboarding/PickServer/TableViewCell/PickServerCell.swift index ee2471878..2f60a5206 100644 --- a/Mastodon/Scene/Onboarding/PickServer/TableViewCell/PickServerCell.swift +++ b/Mastodon/Scene/Onboarding/PickServer/TableViewCell/PickServerCell.swift @@ -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 { diff --git a/Mastodon/Scene/Onboarding/PickServer/TableViewCell/PickServerLoaderTableViewCell.swift b/Mastodon/Scene/Onboarding/PickServer/TableViewCell/PickServerLoaderTableViewCell.swift index 1b8264ec3..945ecac6a 100644 --- a/Mastodon/Scene/Onboarding/PickServer/TableViewCell/PickServerLoaderTableViewCell.swift +++ b/Mastodon/Scene/Onboarding/PickServer/TableViewCell/PickServerLoaderTableViewCell.swift @@ -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 diff --git a/Mastodon/Scene/Onboarding/PickServer/TableViewCell/PickServerSearchCell.swift b/Mastodon/Scene/Onboarding/PickServer/TableViewCell/PickServerSearchCell.swift index fa3e3ae27..0a64103d2 100644 --- a/Mastodon/Scene/Onboarding/PickServer/TableViewCell/PickServerSearchCell.swift +++ b/Mastodon/Scene/Onboarding/PickServer/TableViewCell/PickServerSearchCell.swift @@ -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 { diff --git a/Mastodon/Scene/Onboarding/PickServer/TableViewCell/PickServerTitleCell.swift b/Mastodon/Scene/Onboarding/PickServer/TableViewCell/PickServerTitleCell.swift index 682ebbf30..f0d78eb41 100644 --- a/Mastodon/Scene/Onboarding/PickServer/TableViewCell/PickServerTitleCell.swift +++ b/Mastodon/Scene/Onboarding/PickServer/TableViewCell/PickServerTitleCell.swift @@ -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 + } } } diff --git a/Mastodon/Scene/Onboarding/Register/MastodonRegisterViewController.swift b/Mastodon/Scene/Onboarding/Register/MastodonRegisterViewController.swift index ffef3d872..b86c46745 100644 --- a/Mastodon/Scene/Onboarding/Register/MastodonRegisterViewController.swift +++ b/Mastodon/Scene/Onboarding/Register/MastodonRegisterViewController.swift @@ -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) diff --git a/Mastodon/Scene/Onboarding/ServerRules/MastodonServerRulesViewController.swift b/Mastodon/Scene/Onboarding/ServerRules/MastodonServerRulesViewController.swift index b9a332d05..e93d06e19 100644 --- a/Mastodon/Scene/Onboarding/ServerRules/MastodonServerRulesViewController.swift +++ b/Mastodon/Scene/Onboarding/ServerRules/MastodonServerRulesViewController.swift @@ -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 { diff --git a/Mastodon/Scene/Onboarding/Share/OnboardingViewControllerAppearance.swift b/Mastodon/Scene/Onboarding/Share/OnboardingViewControllerAppearance.swift index d93c677f8..4a4d04bf6 100644 --- a/Mastodon/Scene/Onboarding/Share/OnboardingViewControllerAppearance.swift +++ b/Mastodon/Scene/Onboarding/Share/OnboardingViewControllerAppearance.swift @@ -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 + } +} diff --git a/Mastodon/Scene/Onboarding/Welcome/WelcomeViewController.swift b/Mastodon/Scene/Onboarding/Welcome/WelcomeViewController.swift index 705ae6132..a2a266f9d 100644 --- a/Mastodon/Scene/Onboarding/Welcome/WelcomeViewController.swift +++ b/Mastodon/Scene/Onboarding/Welcome/WelcomeViewController.swift @@ -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 + } } } diff --git a/Mastodon/Scene/Root/MainTab/MainTabBarController.swift b/Mastodon/Scene/Root/MainTab/MainTabBarController.swift index 1681b6171..d24a67c4a 100644 --- a/Mastodon/Scene/Root/MainTab/MainTabBarController.swift +++ b/Mastodon/Scene/Root/MainTab/MainTabBarController.swift @@ -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 { diff --git a/Mastodon/Scene/Root/RootSplitViewController.swift b/Mastodon/Scene/Root/RootSplitViewController.swift index 2e8beef9e..15464c9db 100644 --- a/Mastodon/Scene/Root/RootSplitViewController.swift +++ b/Mastodon/Scene/Root/RootSplitViewController.swift @@ -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 }