diff --git a/Mastodon.xcodeproj/project.pbxproj b/Mastodon.xcodeproj/project.pbxproj index fca6eb8b5..ae8410c35 100644 --- a/Mastodon.xcodeproj/project.pbxproj +++ b/Mastodon.xcodeproj/project.pbxproj @@ -91,6 +91,7 @@ D87BFC8B291D5C6B00FEE264 /* MastodonLoginView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D87BFC8A291D5C6B00FEE264 /* MastodonLoginView.swift */; }; D87BFC8D291EB81200FEE264 /* MastodonLoginViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D87BFC8C291EB81200FEE264 /* MastodonLoginViewModel.swift */; }; D87BFC8F291EC26A00FEE264 /* MastodonLoginServerTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D87BFC8E291EC26A00FEE264 /* MastodonLoginServerTableViewCell.swift */; }; + D8916DC029211BE500124085 /* ContentSizedTableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8916DBF29211BE500124085 /* ContentSizedTableView.swift */; }; D8A6AB6C291C5136003AB663 /* MastodonLoginViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8A6AB6B291C5136003AB663 /* MastodonLoginViewController.swift */; }; DB0009A626AEE5DC009B9D2D /* Intents.intentdefinition in Sources */ = {isa = PBXBuildFile; fileRef = DB0009A926AEE5DC009B9D2D /* Intents.intentdefinition */; settings = {ATTRIBUTES = (codegen, ); }; }; DB0009A726AEE5DC009B9D2D /* Intents.intentdefinition in Sources */ = {isa = PBXBuildFile; fileRef = DB0009A926AEE5DC009B9D2D /* Intents.intentdefinition */; }; @@ -615,6 +616,7 @@ D87BFC8A291D5C6B00FEE264 /* MastodonLoginView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MastodonLoginView.swift; sourceTree = ""; }; D87BFC8C291EB81200FEE264 /* MastodonLoginViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MastodonLoginViewModel.swift; sourceTree = ""; }; D87BFC8E291EC26A00FEE264 /* MastodonLoginServerTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MastodonLoginServerTableViewCell.swift; sourceTree = ""; }; + D8916DBF29211BE500124085 /* ContentSizedTableView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentSizedTableView.swift; sourceTree = ""; }; D8A6AB6B291C5136003AB663 /* MastodonLoginViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MastodonLoginViewController.swift; sourceTree = ""; }; DB0009A826AEE5DC009B9D2D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.intentdefinition; name = Base; path = Base.lproj/Intents.intentdefinition; sourceTree = ""; }; DB0009AD26AEE5E4009B9D2D /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = ar.lproj/Intents.strings; sourceTree = ""; }; @@ -1509,6 +1511,7 @@ D87BFC8A291D5C6B00FEE264 /* MastodonLoginView.swift */, D87BFC8C291EB81200FEE264 /* MastodonLoginViewModel.swift */, D87BFC8E291EC26A00FEE264 /* MastodonLoginServerTableViewCell.swift */, + D8916DBF29211BE500124085 /* ContentSizedTableView.swift */, ); path = Login; sourceTree = ""; @@ -3311,6 +3314,7 @@ DB63F769279A5EBB00455B82 /* NotificationTimelineViewModel+Diffable.swift in Sources */, DBFEEC9B279BDDD9004F81DD /* ProfileAboutViewModel+Diffable.swift in Sources */, DBB525562611EDCA002F1F29 /* UserTimelineViewModel.swift in Sources */, + D8916DC029211BE500124085 /* ContentSizedTableView.swift in Sources */, DB0618012785732C0030EE79 /* ServerRulesTableViewCell.swift in Sources */, DB98EB5C27B10A730082E365 /* ReportSupplementaryViewModel.swift in Sources */, DB0617EF277F12720030EE79 /* NavigationActionView.swift in Sources */, diff --git a/Mastodon/Scene/Onboarding/Login/ContentSizedTableView.swift b/Mastodon/Scene/Onboarding/Login/ContentSizedTableView.swift new file mode 100644 index 000000000..e0c8a9228 --- /dev/null +++ b/Mastodon/Scene/Onboarding/Login/ContentSizedTableView.swift @@ -0,0 +1,22 @@ +// +// MastodonLoginTableView.swift +// Mastodon +// +// Created by Nathan Mattes on 13.11.22. +// + +import UIKit + +// Source: https://stackoverflow.com/a/48623673 +final class ContentSizedTableView: UITableView { + override var contentSize:CGSize { + didSet { + invalidateIntrinsicContentSize() + } + } + + override var intrinsicContentSize: CGSize { + layoutIfNeeded() + return CGSize(width: UIView.noIntrinsicMetric, height: contentSize.height) + } +} diff --git a/Mastodon/Scene/Onboarding/Login/MastodonLoginView.swift b/Mastodon/Scene/Onboarding/Login/MastodonLoginView.swift index 9fb5f425a..53ed98997 100644 --- a/Mastodon/Scene/Onboarding/Login/MastodonLoginView.swift +++ b/Mastodon/Scene/Onboarding/Login/MastodonLoginView.swift @@ -10,7 +10,6 @@ import MastodonAsset class MastodonLoginView: UIView { - // SearchBox, queries api.joinmastodon.org/servers with domain // List with (filtered) domains let titleLabel: UILabel @@ -46,14 +45,17 @@ class MastodonLoginView: UIView { searchTextField.placeholder = "Search for your server" //TODO: @zeitschlag Localization searchTextField.leftView = UIImageView(image: UIImage(systemName: "magnifyingglass")) searchTextField.leftViewMode = .always + searchTextField.layer.cornerRadius = 10 - tableView = UITableView() + tableView = ContentSizedTableView() tableView.translatesAutoresizingMaskIntoConstraints = false - tableView.backgroundColor = Asset.Scene.Onboarding.background.color + tableView.backgroundColor = Asset.Scene.Onboarding.textFieldBackground.color tableViewWrapper = UIView() tableViewWrapper.translatesAutoresizingMaskIntoConstraints = false tableViewWrapper.backgroundColor = .clear + tableViewWrapper.layer.cornerRadius = 10 + tableViewWrapper.layer.masksToBounds = true tableViewWrapper.addSubview(tableView) navigationActionView = NavigationActionView() @@ -89,12 +91,12 @@ class MastodonLoginView: UIView { tableViewWrapper.topAnchor.constraint(equalTo: searchTextField.bottomAnchor), tableViewWrapper.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 16), trailingAnchor.constraint(equalTo: tableViewWrapper.trailingAnchor, constant: 16), - tableViewWrapper.bottomAnchor.constraint(equalTo: navigationActionView.topAnchor), + tableViewWrapper.bottomAnchor.constraint(lessThanOrEqualTo: navigationActionView.topAnchor), tableView.topAnchor.constraint(equalTo: tableViewWrapper.topAnchor), tableView.leadingAnchor.constraint(equalTo: tableViewWrapper.leadingAnchor), tableViewWrapper.trailingAnchor.constraint(equalTo: tableView.trailingAnchor), - tableViewWrapper.bottomAnchor.constraint(equalTo: tableView.bottomAnchor), + tableViewWrapper.bottomAnchor.constraint(greaterThanOrEqualTo: tableView.bottomAnchor), navigationActionView.leadingAnchor.constraint(equalTo: leadingAnchor), navigationActionView.trailingAnchor.constraint(equalTo: trailingAnchor), @@ -104,26 +106,18 @@ class MastodonLoginView: UIView { } func updateCorners(numberOfResults: Int = 0) { - let tableViewPath = UIBezierPath(roundedRect:tableViewWrapper.bounds, - byRoundingCorners: [.bottomLeft, .bottomRight], - cornerRadii: CGSize(width: 10, height: 10)) - let tableViewMask = CAShapeLayer() - tableViewMask.path = tableViewPath.cgPath - tableViewWrapper.layer.mask = tableViewMask + tableView.isHidden = (numberOfResults == 0) + tableViewWrapper.layer.maskedCorners = [.layerMinXMaxYCorner, .layerMaxXMaxYCorner] // tableViewMask + + let maskedCorners: CACornerMask - let searchFieldCorners: UIRectCorner if numberOfResults == 0 { - searchFieldCorners = .allCorners + maskedCorners = [.layerMinXMinYCorner, .layerMinXMaxYCorner, .layerMaxXMinYCorner, .layerMaxXMaxYCorner] } else { - searchFieldCorners = [.topLeft, .topRight] + maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner] } - let searchFieldPath = UIBezierPath(roundedRect: searchTextField.bounds, - byRoundingCorners: searchFieldCorners, - cornerRadii: CGSize(width: 10, height: 10)) - let searchFieldMask = CAShapeLayer() - searchFieldMask.path = searchFieldPath.cgPath - searchTextField.layer.mask = searchFieldMask + searchTextField.layer.maskedCorners = maskedCorners } } diff --git a/Mastodon/Scene/Onboarding/Login/MastodonLoginViewController.swift b/Mastodon/Scene/Onboarding/Login/MastodonLoginViewController.swift index 267b27c15..780cc932c 100644 --- a/Mastodon/Scene/Onboarding/Login/MastodonLoginViewController.swift +++ b/Mastodon/Scene/Onboarding/Login/MastodonLoginViewController.swift @@ -83,12 +83,22 @@ class MastodonLoginViewController: UIViewController { cell.backgroundColor = .systemBackground } + if self.viewModel.serverList.last == server { + cell.layer.maskedCorners = [.layerMinXMaxYCorner, .layerMaxXMaxYCorner] + cell.layer.cornerRadius = 10 + cell.layer.masksToBounds = true + } else { + cell.layer.masksToBounds = false + } + return cell } contentView.tableView.dataSource = dataSource self.dataSource = dataSource + contentView.updateCorners() + defer { setupNavigationBarBackgroundView() } setupOnboardingAppearance() } @@ -187,9 +197,11 @@ extension MastodonLoginViewController: MastodonLoginViewModelDelegate { snapshot.appendSections([MastodonLoginViewSection.servers]) snapshot.appendItems(viewModel.serverList) - dataSource?.applySnapshot(snapshot, animated: true) + dataSource?.applySnapshot(snapshot, animated: false) + OperationQueue.main.addOperation { - self.contentView.updateCorners(numberOfResults: viewModel.serverList.count) + let numberOfResults = viewModel.serverList.count + self.contentView.updateCorners(numberOfResults: numberOfResults) } } }