1
0
mirror of https://github.com/mastodon/mastodon-ios.git synced 2025-02-03 10:47:35 +01:00

Replace NavigationActionView with a view with a simple button (#690)

This commit is contained in:
Nathan Mattes 2022-12-13 23:23:20 +01:00
parent 3a176edb91
commit d3ebd51d44
3 changed files with 100 additions and 69 deletions

View File

@ -110,6 +110,7 @@
9E44C7202967AD17004B2A72 /* MastodonSDKDynamic in Frameworks */ = {isa = PBXBuildFile; productRef = 9E44C71F2967AD17004B2A72 /* MastodonSDKDynamic */; }; 9E44C7202967AD17004B2A72 /* MastodonSDKDynamic in Frameworks */ = {isa = PBXBuildFile; productRef = 9E44C71F2967AD17004B2A72 /* MastodonSDKDynamic */; };
9E44C7222967AD17004B2A72 /* MastodonSDKDynamic in Embed Frameworks */ = {isa = PBXBuildFile; productRef = 9E44C71F2967AD17004B2A72 /* MastodonSDKDynamic */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; }; 9E44C7222967AD17004B2A72 /* MastodonSDKDynamic in Embed Frameworks */ = {isa = PBXBuildFile; productRef = 9E44C71F2967AD17004B2A72 /* MastodonSDKDynamic */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
C24C97032922F30500BAE8CB /* RefreshControl.swift in Sources */ = {isa = PBXBuildFile; fileRef = C24C97022922F30500BAE8CB /* RefreshControl.swift */; }; C24C97032922F30500BAE8CB /* RefreshControl.swift in Sources */ = {isa = PBXBuildFile; fileRef = C24C97022922F30500BAE8CB /* RefreshControl.swift */; };
D8363B1629469CE200A74079 /* OnboardingNextView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8363B1529469CE200A74079 /* OnboardingNextView.swift */; };
D87BFC8B291D5C6B00FEE264 /* MastodonLoginView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D87BFC8A291D5C6B00FEE264 /* MastodonLoginView.swift */; }; D87BFC8B291D5C6B00FEE264 /* MastodonLoginView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D87BFC8A291D5C6B00FEE264 /* MastodonLoginView.swift */; };
D87BFC8D291EB81200FEE264 /* MastodonLoginViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D87BFC8C291EB81200FEE264 /* MastodonLoginViewModel.swift */; }; D87BFC8D291EB81200FEE264 /* MastodonLoginViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D87BFC8C291EB81200FEE264 /* MastodonLoginViewModel.swift */; };
D87BFC8F291EC26A00FEE264 /* MastodonLoginServerTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D87BFC8E291EC26A00FEE264 /* MastodonLoginServerTableViewCell.swift */; }; D87BFC8F291EC26A00FEE264 /* MastodonLoginServerTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D87BFC8E291EC26A00FEE264 /* MastodonLoginServerTableViewCell.swift */; };
@ -658,6 +659,7 @@
C3789232A52F43529CA67E95 /* Pods-MastodonIntent.asdk - debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MastodonIntent.asdk - debug.xcconfig"; path = "Target Support Files/Pods-MastodonIntent/Pods-MastodonIntent.asdk - debug.xcconfig"; sourceTree = "<group>"; }; C3789232A52F43529CA67E95 /* Pods-MastodonIntent.asdk - debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MastodonIntent.asdk - debug.xcconfig"; path = "Target Support Files/Pods-MastodonIntent/Pods-MastodonIntent.asdk - debug.xcconfig"; sourceTree = "<group>"; };
CD92E0F10BDE4FE7C4B999F2 /* Pods_MastodonTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_MastodonTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; CD92E0F10BDE4FE7C4B999F2 /* Pods_MastodonTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_MastodonTests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
D7D7CF93E262178800077512 /* Pods-Mastodon-AppShared.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Mastodon-AppShared.debug.xcconfig"; path = "Target Support Files/Pods-Mastodon-AppShared/Pods-Mastodon-AppShared.debug.xcconfig"; sourceTree = "<group>"; }; D7D7CF93E262178800077512 /* Pods-Mastodon-AppShared.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Mastodon-AppShared.debug.xcconfig"; path = "Target Support Files/Pods-Mastodon-AppShared/Pods-Mastodon-AppShared.debug.xcconfig"; sourceTree = "<group>"; };
D8363B1529469CE200A74079 /* OnboardingNextView.swift */ = {isa = PBXFileReference; indentWidth = 4; lastKnownFileType = sourcecode.swift; path = OnboardingNextView.swift; sourceTree = "<group>"; tabWidth = 4; };
D87BFC8A291D5C6B00FEE264 /* MastodonLoginView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MastodonLoginView.swift; sourceTree = "<group>"; }; D87BFC8A291D5C6B00FEE264 /* MastodonLoginView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MastodonLoginView.swift; sourceTree = "<group>"; };
D87BFC8C291EB81200FEE264 /* MastodonLoginViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MastodonLoginViewModel.swift; sourceTree = "<group>"; }; D87BFC8C291EB81200FEE264 /* MastodonLoginViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MastodonLoginViewModel.swift; sourceTree = "<group>"; };
D87BFC8E291EC26A00FEE264 /* MastodonLoginServerTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MastodonLoginServerTableViewCell.swift; sourceTree = "<group>"; }; D87BFC8E291EC26A00FEE264 /* MastodonLoginServerTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MastodonLoginServerTableViewCell.swift; sourceTree = "<group>"; };
@ -1217,6 +1219,7 @@
0FB3D30D25E525C000AAD544 /* View */ = { 0FB3D30D25E525C000AAD544 /* View */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
D8363B1529469CE200A74079 /* OnboardingNextView.swift */,
0FB3D30E25E525CD00AAD544 /* PickServerCategoryView.swift */, 0FB3D30E25E525CD00AAD544 /* PickServerCategoryView.swift */,
DB9282B125F3222800823B15 /* PickServerEmptyStateView.swift */, DB9282B125F3222800823B15 /* PickServerEmptyStateView.swift */,
DB0617F0278413D00030EE79 /* PickServerServerSectionTableHeaderView.swift */, DB0617F0278413D00030EE79 /* PickServerServerSectionTableHeaderView.swift */,
@ -3604,6 +3607,7 @@
2A3F6FE5292F6E44002E6DA7 /* FollowedTagsTableViewCell.swift in Sources */, 2A3F6FE5292F6E44002E6DA7 /* FollowedTagsTableViewCell.swift in Sources */,
C24C97032922F30500BAE8CB /* RefreshControl.swift in Sources */, C24C97032922F30500BAE8CB /* RefreshControl.swift in Sources */,
DB023D2A27A0FE5C005AC798 /* DataSourceProvider+NotificationTableViewCellDelegate.swift in Sources */, DB023D2A27A0FE5C005AC798 /* DataSourceProvider+NotificationTableViewCellDelegate.swift in Sources */,
D8363B1629469CE200A74079 /* OnboardingNextView.swift in Sources */,
DB98EB6027B10E150082E365 /* ReportCommentTableViewCell.swift in Sources */, DB98EB6027B10E150082E365 /* ReportCommentTableViewCell.swift in Sources */,
DB0FCB962797E6C2006C02E2 /* SearchResultViewController+DataSourceProvider.swift in Sources */, DB0FCB962797E6C2006C02E2 /* SearchResultViewController+DataSourceProvider.swift in Sources */,
DB6180E326391A4C0018D199 /* ViewControllerAnimatedTransitioning.swift in Sources */, DB6180E326391A4C0018D199 /* ViewControllerAnimatedTransitioning.swift in Sources */,

View File

@ -46,20 +46,15 @@ final class MastodonPickServerViewController: UIViewController, NeedsDependency
tableView.sectionHeaderTopPadding = .leastNonzeroMagnitude tableView.sectionHeaderTopPadding = .leastNonzeroMagnitude
return tableView return tableView
}() }()
let navigationActionView: NavigationActionView = { let onboardingNextView: OnboardingNextView = {
let navigationActionView = NavigationActionView() let onboardingNextView = OnboardingNextView()
navigationActionView.backgroundColor = Asset.Scene.Onboarding.background.color onboardingNextView.translatesAutoresizingMaskIntoConstraints = false
return navigationActionView onboardingNextView.backgroundColor = UIColor.secondarySystemBackground
return onboardingNextView
}() }()
var mastodonAuthenticationController: MastodonAuthenticationController? var mastodonAuthenticationController: MastodonAuthenticationController?
deinit {
tableViewObservation = nil
os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s", ((#file as NSString).lastPathComponent), #line, #function)
}
} }
extension MastodonPickServerViewController { extension MastodonPickServerViewController {
@ -72,17 +67,6 @@ extension MastodonPickServerViewController {
setupOnboardingAppearance() setupOnboardingAppearance()
defer { setupNavigationBarBackgroundView() } defer { setupNavigationBarBackgroundView() }
#if DEBUG
navigationItem.rightBarButtonItem = UIBarButtonItem(image: UIImage(systemName: "ellipsis.circle"), style: .plain, target: nil, action: nil)
let children: [UIMenuElement] = [
UIAction(title: "Dismiss", image: nil, identifier: nil, discoverabilityTitle: nil, attributes: [], state: .off, handler: { [weak self] _ in
guard let self = self else { return }
self.dismiss(animated: true, completion: nil)
})
]
navigationItem.rightBarButtonItem?.menu = UIMenu(title: "Debug Tool", image: nil, identifier: nil, options: [], children: children)
#endif
tableView.translatesAutoresizingMaskIntoConstraints = false tableView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(tableView) view.addSubview(tableView)
NSLayoutConstraint.activate([ NSLayoutConstraint.activate([
@ -92,37 +76,22 @@ extension MastodonPickServerViewController {
tableView.bottomAnchor.constraint(equalTo: view.layoutMarginsGuide.bottomAnchor), tableView.bottomAnchor.constraint(equalTo: view.layoutMarginsGuide.bottomAnchor),
]) ])
navigationActionView.translatesAutoresizingMaskIntoConstraints = false view.addSubview(onboardingNextView)
view.addSubview(navigationActionView)
defer {
view.bringSubviewToFront(navigationActionView)
}
NSLayoutConstraint.activate([ NSLayoutConstraint.activate([
navigationActionView.leadingAnchor.constraint(equalTo: view.leadingAnchor), onboardingNextView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
navigationActionView.trailingAnchor.constraint(equalTo: view.trailingAnchor), onboardingNextView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
view.bottomAnchor.constraint(equalTo: navigationActionView.bottomAnchor), view.bottomAnchor.constraint(equalTo: onboardingNextView.bottomAnchor),
]) ])
navigationActionView onboardingNextView
.observe(\.bounds, options: [.initial, .new]) { [weak self] _, _ in .observe(\.bounds, options: [.initial, .new]) { [weak self] _, _ in
guard let self = self else { return } guard let self = self else { return }
let inset = self.navigationActionView.frame.height let inset = self.onboardingNextView.frame.height
self.viewModel.additionalTableViewInsets.bottom = inset self.viewModel.additionalTableViewInsets.bottom = inset
} }
.store(in: &observations) .store(in: &observations)
// fix AutoLayout warning when observe before view appear
viewModel.viewWillAppear
.receive(on: DispatchQueue.main)
.sink { [weak self] in
guard let self = self else { return }
self.tableViewObservation = self.tableView.observe(\.contentSize, options: [.initial, .new]) { [weak self] tableView, _ in
guard let self = self else { return }
self.updateEmptyStateViewLayout()
}
}
.store(in: &disposeBag)
emptyStateView.translatesAutoresizingMaskIntoConstraints = false emptyStateView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(emptyStateView) view.addSubview(emptyStateView)
emptyStateViewLeadingLayoutConstraint = emptyStateView.leadingAnchor.constraint(equalTo: tableView.leadingAnchor) emptyStateViewLeadingLayoutConstraint = emptyStateView.leadingAnchor.constraint(equalTo: tableView.leadingAnchor)
@ -131,7 +100,7 @@ extension MastodonPickServerViewController {
emptyStateView.topAnchor.constraint(equalTo: view.topAnchor), emptyStateView.topAnchor.constraint(equalTo: view.topAnchor),
emptyStateViewLeadingLayoutConstraint, emptyStateViewLeadingLayoutConstraint,
emptyStateViewTrailingLayoutConstraint, emptyStateViewTrailingLayoutConstraint,
navigationActionView.topAnchor.constraint(equalTo: emptyStateView.bottomAnchor, constant: 21), onboardingNextView.topAnchor.constraint(equalTo: emptyStateView.bottomAnchor, constant: 21),
]) ])
view.sendSubviewToBack(emptyStateView) view.sendSubviewToBack(emptyStateView)
@ -153,7 +122,7 @@ extension MastodonPickServerViewController {
viewModel viewModel
.selectedServer .selectedServer
.map { $0 != nil } .map { $0 != nil }
.assign(to: \.isEnabled, on: navigationActionView.nextButton) .assign(to: \.isEnabled, on: onboardingNextView.nextButton)
.store(in: &disposeBag) .store(in: &disposeBag)
Publishers.Merge( Publishers.Merge(
@ -203,7 +172,7 @@ extension MastodonPickServerViewController {
.receive(on: DispatchQueue.main) .receive(on: DispatchQueue.main)
.sink { [weak self] isAuthenticating in .sink { [weak self] isAuthenticating in
guard let self = self else { return } guard let self = self else { return }
isAuthenticating ? self.navigationActionView.nextButton.showLoading() : self.navigationActionView.nextButton.stopLoading() // isAuthenticating ? self.navigationActionView.nextButton.showLoading() : self.navigationActionView.nextButton.stopLoading()
} }
.store(in: &disposeBag) .store(in: &disposeBag)
@ -234,7 +203,7 @@ extension MastodonPickServerViewController {
} }
.store(in: &disposeBag) .store(in: &disposeBag)
navigationActionView.nextButton.addTarget(self, action: #selector(MastodonPickServerViewController.nextButtonDidPressed(_:)), for: .touchUpInside) onboardingNextView.nextButton.addTarget(self, action: #selector(MastodonPickServerViewController.nextButtonDidPressed(_:)), for: .touchUpInside)
} }
override func viewWillAppear(_ animated: Bool) { override func viewWillAppear(_ animated: Bool) {
@ -253,7 +222,6 @@ extension MastodonPickServerViewController {
super.traitCollectionDidChange(previousTraitCollection) super.traitCollectionDidChange(previousTraitCollection)
setupNavigationBarAppearance() setupNavigationBarAppearance()
updateEmptyStateViewLayout()
} }
} }
@ -407,26 +375,6 @@ extension MastodonPickServerViewController: UITableViewDelegate {
} }
extension MastodonPickServerViewController {
private func updateEmptyStateViewLayout() {
// guard let diffableDataSource = self.viewModel.diffableDataSource else { return }
// guard let indexPath = diffableDataSource.indexPath(for: .search) else { return }
// 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
// }
}
}
// MARK: - PickServerServerSectionTableHeaderViewDelegate // MARK: - PickServerServerSectionTableHeaderViewDelegate
extension MastodonPickServerViewController: PickServerServerSectionTableHeaderViewDelegate { extension MastodonPickServerViewController: PickServerServerSectionTableHeaderViewDelegate {
func pickServerServerSectionTableHeaderView(_ headerView: PickServerServerSectionTableHeaderView, collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { func pickServerServerSectionTableHeaderView(_ headerView: PickServerServerSectionTableHeaderView, collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {

View File

@ -0,0 +1,79 @@
//
// OnboardingNextView.swift
// Mastodon
//
// Created by Nathan Mattes on 2022-12-12.
//
import UIKit
import MastodonUI
import MastodonAsset
import MastodonLocalization
final class OnboardingNextView: UIView {
static let buttonHeight: CGFloat = 50
static let minimumBackButtonWidth: CGFloat = 100
private var observations = Set<NSKeyValueObservation>()
private let container: UIStackView = {
let stackView = UIStackView()
stackView.axis = .vertical
stackView.spacing = 8
stackView.alignment = .center
return stackView
}()
//TODO: Show loading
let nextButton: UIButton = {
let button = UIButton()
button.translatesAutoresizingMaskIntoConstraints = false
button.layer.cornerRadius = 14
button.backgroundColor = Asset.Colors.brand.color
button.setTitle(L10n.Common.Controls.Actions.next, for: .normal)
return button
}()
let explanationLabel: UILabel = {
let label = UILabel()
label.numberOfLines = 0
label.textColor = .secondaryLabel
label.font = UIFontMetrics(forTextStyle: .footnote).scaledFont(for: .systemFont(ofSize: 13, weight: .regular))
label.text = "Well pick a server based on your language if you continue without making a selection." //TODO: @zeitschlag localize
return label
}()
override init(frame: CGRect) {
super.init(frame: frame)
_init()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
_init()
}
private func _init() {
container.translatesAutoresizingMaskIntoConstraints = false
container.addArrangedSubview(nextButton)
container.addArrangedSubview(explanationLabel)
addSubview(container)
NSLayoutConstraint.activate([
container.topAnchor.constraint(equalTo: topAnchor, constant: 16),
container.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 16),
trailingAnchor.constraint(equalTo: container.trailingAnchor, constant: 16),
safeAreaLayoutGuide.bottomAnchor.constraint(equalTo: container.bottomAnchor, constant: 16),
nextButton.widthAnchor.constraint(equalTo: container.widthAnchor),
explanationLabel.widthAnchor.constraint(equalTo: container.widthAnchor),
])
NSLayoutConstraint.activate([
nextButton.heightAnchor.constraint(greaterThanOrEqualToConstant: NavigationActionView.buttonHeight)
])
}
}