From eaa915f96c59983760e52d7e4430801aad1259a6 Mon Sep 17 00:00:00 2001 From: CMK Date: Mon, 27 Sep 2021 16:30:36 +0800 Subject: [PATCH] feat: update scene modal style and update Settings scene tableView style --- Mastodon.xcodeproj/project.pbxproj | 4 ++ Mastodon/Coordinator/SceneCoordinator.swift | 2 +- .../MastodonServerRulesViewController.swift | 6 +++ .../Welcome/WelcomeViewController.swift | 13 +++++- .../Scene/Root/Sidebar/SidebarViewModel.swift | 30 +++++++++----- .../SidebarAddAccountCollectionViewCell.swift | 41 +++++++++++++++++++ .../Settings/SettingsViewController.swift | 10 ++++- 7 files changed, 91 insertions(+), 15 deletions(-) create mode 100644 Mastodon/Scene/Root/Sidebar/View/SidebarAddAccountCollectionViewCell.swift diff --git a/Mastodon.xcodeproj/project.pbxproj b/Mastodon.xcodeproj/project.pbxproj index 8de9739e0..1dbb546e0 100644 --- a/Mastodon.xcodeproj/project.pbxproj +++ b/Mastodon.xcodeproj/project.pbxproj @@ -572,6 +572,7 @@ DBE3CE13261D7D4200430CC6 /* StatusTableViewControllerAspect.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBE3CE12261D7D4200430CC6 /* StatusTableViewControllerAspect.swift */; }; DBE54AC62636C89F004E7C0B /* NotificationPreference.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBE54AC52636C89F004E7C0B /* NotificationPreference.swift */; }; DBE54ACC2636C8FD004E7C0B /* NotificationPreference.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBE54AC52636C89F004E7C0B /* NotificationPreference.swift */; }; + DBF156DF2701B17600EC00B7 /* SidebarAddAccountCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBF156DE2701B17600EC00B7 /* SidebarAddAccountCollectionViewCell.swift */; }; DBF1D24E269DAF5D00C1C08A /* SearchDetailViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBF1D24D269DAF5D00C1C08A /* SearchDetailViewController.swift */; }; DBF1D251269DB01200C1C08A /* SearchHistoryViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBF1D250269DB01200C1C08A /* SearchHistoryViewController.swift */; }; DBF1D257269DBAC600C1C08A /* SearchDetailViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBF1D256269DBAC600C1C08A /* SearchDetailViewModel.swift */; }; @@ -1353,6 +1354,7 @@ DBE3CE12261D7D4200430CC6 /* StatusTableViewControllerAspect.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatusTableViewControllerAspect.swift; sourceTree = ""; }; DBE54AC52636C89F004E7C0B /* NotificationPreference.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationPreference.swift; sourceTree = ""; }; DBF156DD27006F5D00EC00B7 /* CoreData 2.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "CoreData 2.xcdatamodel"; sourceTree = ""; }; + DBF156DE2701B17600EC00B7 /* SidebarAddAccountCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SidebarAddAccountCollectionViewCell.swift; sourceTree = ""; }; DBF1D24D269DAF5D00C1C08A /* SearchDetailViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchDetailViewController.swift; sourceTree = ""; }; DBF1D250269DB01200C1C08A /* SearchHistoryViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchHistoryViewController.swift; sourceTree = ""; }; DBF1D256269DBAC600C1C08A /* SearchDetailViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchDetailViewModel.swift; sourceTree = ""; }; @@ -2090,6 +2092,7 @@ DB0EF72C26FDB1D600347686 /* View */ = { isa = PBXGroup; children = ( + DBF156DE2701B17600EC00B7 /* SidebarAddAccountCollectionViewCell.swift */, DB0EF72A26FDB1D200347686 /* SidebarListCollectionViewCell.swift */, DB0EF72D26FDB24F00347686 /* SidebarListContentView.swift */, ); @@ -3906,6 +3909,7 @@ DB72601C25E36A2100235243 /* MastodonServerRulesViewController.swift in Sources */, DBB5250E2611EBAF002F1F29 /* ProfileSegmentedViewController.swift in Sources */, 2D42FF8F25C8228A004A627A /* UIButton.swift in Sources */, + DBF156DF2701B17600EC00B7 /* SidebarAddAccountCollectionViewCell.swift in Sources */, DB789A0B25F9F2950071ACA0 /* ComposeViewController.swift in Sources */, DB938F0926240F3C00E5B6C1 /* RemoteThreadViewModel.swift in Sources */, DBBC24AE26A53DC100398BB9 /* ReplicaStatusView.swift in Sources */, diff --git a/Mastodon/Coordinator/SceneCoordinator.swift b/Mastodon/Coordinator/SceneCoordinator.swift index 4978c0a7e..216394c50 100644 --- a/Mastodon/Coordinator/SceneCoordinator.swift +++ b/Mastodon/Coordinator/SceneCoordinator.swift @@ -213,7 +213,7 @@ extension SceneCoordinator { case .custom(let transitioningDelegate): viewController.modalPresentationStyle = .custom viewController.transitioningDelegate = transitioningDelegate - sender?.present(viewController, animated: true, completion: nil) + (splitViewController ?? presentingViewController)?.present(viewController, animated: true, completion: nil) case .customPush: // set delegate in view controller diff --git a/Mastodon/Scene/Onboarding/ServerRules/MastodonServerRulesViewController.swift b/Mastodon/Scene/Onboarding/ServerRules/MastodonServerRulesViewController.swift index c31e91304..b9a332d05 100644 --- a/Mastodon/Scene/Onboarding/ServerRules/MastodonServerRulesViewController.swift +++ b/Mastodon/Scene/Onboarding/ServerRules/MastodonServerRulesViewController.swift @@ -162,6 +162,12 @@ extension MastodonServerRulesViewController { confirmButton.addTarget(self, action: #selector(MastodonServerRulesViewController.confirmButtonPressed(_:)), for: .touchUpInside) } + override func viewDidAppear(_ animated: Bool) { + super.viewDidAppear(animated) + + scrollView.flashScrollIndicators() + } + override func viewDidLayoutSubviews() { super.viewDidLayoutSubviews() updateScrollViewContentInset() diff --git a/Mastodon/Scene/Onboarding/Welcome/WelcomeViewController.swift b/Mastodon/Scene/Onboarding/Welcome/WelcomeViewController.swift index e424d350a..705ae6132 100644 --- a/Mastodon/Scene/Onboarding/Welcome/WelcomeViewController.swift +++ b/Mastodon/Scene/Onboarding/Welcome/WelcomeViewController.swift @@ -240,7 +240,16 @@ extension WelcomeViewController: OnboardingViewControllerAppearance { } // MARK: - UIAdaptivePresentationControllerDelegate extension WelcomeViewController: UIAdaptivePresentationControllerDelegate { func adaptivePresentationStyle(for controller: UIPresentationController, traitCollection: UITraitCollection) -> UIModalPresentationStyle { - // make underneath view controller alive to fix layout issue due to view life cycle - return .fullScreen + switch traitCollection.userInterfaceIdiom { + case .phone: + // make underneath view controller alive to fix layout issue due to view life cycle + return .fullScreen + default: + return .pageSheet + } + } + + func presentationControllerShouldDismiss(_ presentationController: UIPresentationController) -> Bool { + return false } } diff --git a/Mastodon/Scene/Root/Sidebar/SidebarViewModel.swift b/Mastodon/Scene/Root/Sidebar/SidebarViewModel.swift index a6dd82cc8..d7ec5b717 100644 --- a/Mastodon/Scene/Root/Sidebar/SidebarViewModel.swift +++ b/Mastodon/Scene/Root/Sidebar/SidebarViewModel.swift @@ -21,7 +21,7 @@ final class SidebarViewModel { let searchHistoryFetchedResultController: SearchHistoryFetchedResultController // output - var diffableDataSource: UICollectionViewDiffableDataSource! + var diffableDataSource: UICollectionViewDiffableDataSource? let activeMastodonAuthenticationObjectID = CurrentValueSubject(nil) init(context: AppContext) { @@ -184,7 +184,12 @@ extension SidebarViewModel { let accountRegistration = UICollectionView.CellRegistration { [weak self] (cell, indexPath, item) in guard let self = self else { return } - let authentication = AppContext.shared.managedObjectContext.object(with: item.authenticationObjectID) as! MastodonAuthentication + // accounts maybe already sign-out + // check isDeleted before using + guard let authentication = try? AppContext.shared.managedObjectContext.existingObject(with: item.authenticationObjectID) as? MastodonAuthentication, + !authentication.isDeleted else { + return + } let user = authentication.user let imageURL = user.avatarImageURL() let headline: MetaContent = { @@ -226,15 +231,16 @@ extension SidebarViewModel { .store(in: &cell.disposeBag) } - let addAccountRegistration = UICollectionView.CellRegistration { (cell, indexPath, item) in - var content = cell.defaultContentConfiguration() + let addAccountRegistration = UICollectionView.CellRegistration { (cell, indexPath, item) in + var content = UIListContentConfiguration.sidebarCell() content.text = L10n.Scene.AccountList.addAccount content.image = UIImage(systemName: "plus.square.fill")! + cell.contentConfiguration = content cell.accessories = [] } - diffableDataSource = UICollectionViewDiffableDataSource(collectionView: collectionView) { collectionView, indexPath, item in + let _diffableDataSource = UICollectionViewDiffableDataSource(collectionView: collectionView) { collectionView, indexPath, item in switch item { case .tab(let tab): return collectionView.dequeueConfiguredReusableCell(using: tabCellRegistration, for: indexPath, item: tab) @@ -248,10 +254,11 @@ extension SidebarViewModel { return collectionView.dequeueConfiguredReusableCell(using: addAccountRegistration, for: indexPath, item: AddAccountViewModel()) } } + diffableDataSource = _diffableDataSource var snapshot = NSDiffableDataSourceSnapshot() snapshot.appendSections(Section.allCases) - diffableDataSource.apply(snapshot) + _diffableDataSource.apply(snapshot) for section in Section.allCases { switch section { @@ -264,7 +271,7 @@ extension SidebarViewModel { .tab(.me), ] sectionSnapshot.append(items, to: nil) - diffableDataSource.apply(sectionSnapshot, to: section) + _diffableDataSource.apply(sectionSnapshot, to: section) case .account: var sectionSnapshot = NSDiffableDataSourceSectionSnapshot() let headerItem = Item.header(HeaderViewModel(title: "Accounts")) @@ -272,7 +279,7 @@ extension SidebarViewModel { sectionSnapshot.append([], to: headerItem) sectionSnapshot.append([.addAccount], to: headerItem) sectionSnapshot.expand([headerItem]) - diffableDataSource.apply(sectionSnapshot, to: section) + _diffableDataSource.apply(sectionSnapshot, to: section) } } @@ -312,10 +319,11 @@ extension SidebarViewModel { .receive(on: DispatchQueue.main) .sink { [weak self] authentications in guard let self = self else { return } + guard let diffableDataSource = self.diffableDataSource else { return } // tab - var snapshot = self.diffableDataSource.snapshot() + var snapshot = diffableDataSource.snapshot() snapshot.reloadItems([.tab(.me)]) - self.diffableDataSource.apply(snapshot) + diffableDataSource.apply(snapshot) // account var accountSectionSnapshot = NSDiffableDataSourceSectionSnapshot() @@ -327,7 +335,7 @@ extension SidebarViewModel { accountSectionSnapshot.append(accountItems, to: headerItem) accountSectionSnapshot.append([.addAccount], to: headerItem) accountSectionSnapshot.expand([headerItem]) - self.diffableDataSource.apply(accountSectionSnapshot, to: .account) + diffableDataSource.apply(accountSectionSnapshot, to: .account) } .store(in: &disposeBag) } diff --git a/Mastodon/Scene/Root/Sidebar/View/SidebarAddAccountCollectionViewCell.swift b/Mastodon/Scene/Root/Sidebar/View/SidebarAddAccountCollectionViewCell.swift new file mode 100644 index 000000000..a4bd5833e --- /dev/null +++ b/Mastodon/Scene/Root/Sidebar/View/SidebarAddAccountCollectionViewCell.swift @@ -0,0 +1,41 @@ +// +// SidebarAddAccountCollectionViewCell.swift +// Mastodon +// +// Created by Cirno MainasuK on 2021-9-27. +// + +import UIKit + +final class SidebarAddAccountCollectionViewCell: UICollectionViewListCell { + + override init(frame: CGRect) { + super.init(frame: frame) + _init() + } + + required init?(coder: NSCoder) { + super.init(coder: coder) + _init() + } + +} + +extension SidebarAddAccountCollectionViewCell { + + private func _init() { } + + override func updateConfiguration(using state: UICellConfigurationState) { + var newBackgroundConfiguration = UIBackgroundConfiguration.listSidebarCell().updated(for: state) + + // Customize the background color to use the tint color when the cell is highlighted or selected. + if state.isSelected || state.isHighlighted { + newBackgroundConfiguration.backgroundColor = Asset.Colors.brandBlue.color + } + if state.isHighlighted { + newBackgroundConfiguration.backgroundColorTransformer = .init { $0.withAlphaComponent(0.8) } + } + + backgroundConfiguration = newBackgroundConfiguration + } +} diff --git a/Mastodon/Scene/Settings/SettingsViewController.swift b/Mastodon/Scene/Settings/SettingsViewController.swift index 667752a83..c4658d7da 100644 --- a/Mastodon/Scene/Settings/SettingsViewController.swift +++ b/Mastodon/Scene/Settings/SettingsViewController.swift @@ -98,7 +98,15 @@ class SettingsViewController: UIViewController, NeedsDependency { private(set) lazy var tableView: UITableView = { // init with a frame to fix a conflict ('UIView-Encapsulated-Layout-Width' UIStackView:0x7f8c2b6c0590.width == 0) - let tableView = UITableView(frame: CGRect(x: 0, y: 0, width: 320, height: 320), style: .grouped) + let style: UITableView.Style = { + switch UIDevice.current.userInterfaceIdiom { + case .phone: + return .grouped + default: + return .insetGrouped + } + }() + let tableView = UITableView(frame: CGRect(x: 0, y: 0, width: 320, height: 320), style: style) tableView.translatesAutoresizingMaskIntoConstraints = false tableView.delegate = self tableView.rowHeight = UITableView.automaticDimension