Move more navigation responsibilities into the AppCoordinator

This commit is contained in:
Maurice Parker 2019-07-05 17:45:39 -05:00
parent 19f8f8bc97
commit 15754684a4
6 changed files with 62 additions and 63 deletions

View File

@ -23,7 +23,12 @@ public extension Notification.Name {
class AppCoordinator {
static let fetchAndMergeArticlesQueue = CoalescingQueue(name: "Fetch and Merge Articles", interval: 0.5)
private var rootSplitViewController: UISplitViewController!
private var masterNavigationController: UINavigationController!
private var masterFeedViewController: MasterFeedViewController!
private var masterTimelineViewController: MasterTimelineViewController?
private let fetchAndMergeArticlesQueue = CoalescingQueue(name: "Fetch and Merge Articles", interval: 0.5)
private var articleRowMap = [String: Int]() // articleID: rowIndex
@ -185,6 +190,21 @@ class AppCoordinator {
}
func start() -> UIViewController {
rootSplitViewController = (UIStoryboard.main.instantiateInitialViewController() as! UISplitViewController)
rootSplitViewController.delegate = self
masterNavigationController = (rootSplitViewController.viewControllers.first as! UINavigationController)
masterFeedViewController = UIStoryboard.main.instantiateController(ofType: MasterFeedViewController.self)
masterFeedViewController.coordinator = self
masterNavigationController.pushViewController(masterFeedViewController, animated: false)
// let detailNavigationController = (rootSplitViewController.viewControllers.last as! UINavigationController)
// detailNavigationController.topViewController!.navigationItem.leftBarButtonItem = splitViewController.displayModeButtonItem
return rootSplitViewController
}
// MARK: Notifications
@objc func containerChildrenDidChange(_ note: Notification) {
@ -226,6 +246,24 @@ class AppCoordinator {
// MARK: API
func didSelectFeed(_ indexPath: IndexPath) {
masterTimelineViewController = UIStoryboard.main.instantiateController(ofType: MasterTimelineViewController.self)
masterTimelineViewController!.coordinator = self
currentMasterIndexPath = indexPath
masterNavigationController.pushViewController(masterTimelineViewController!, animated: true)
}
func didSelectArticle(_ indexPath: IndexPath) {
let detailViewController = UIStoryboard.main.instantiateController(ofType: DetailViewController.self)
detailViewController.coordinator = self
detailViewController.navigationItem.leftBarButtonItem = rootSplitViewController.displayModeButtonItem
detailViewController.navigationItem.leftItemsSupplementBackButton = true
currentArticleIndexPath = indexPath
// rootSplitViewController.toggleMasterView()
rootSplitViewController.showDetailViewController(detailViewController, sender: self)
}
func beginUpdates() {
animatingChanges = true
}
@ -608,7 +646,7 @@ private extension AppCoordinator {
}
func queueFetchAndMergeArticles() {
AppCoordinator.fetchAndMergeArticlesQueue.add(self, #selector(fetchAndMergeArticles))
fetchAndMergeArticlesQueue.add(self, #selector(fetchAndMergeArticles))
}
@objc func fetchAndMergeArticles() {

View File

@ -19,9 +19,6 @@
<rect key="frame" x="0.0" y="813" width="414" height="49"/>
<autoresizingMask key="autoresizingMask"/>
</toolbar>
<connections>
<segue destination="7bK-jq-Zjz" kind="relationship" relationship="rootViewController" id="tsl-Nk-0bq"/>
</connections>
</navigationController>
<placeholder placeholderIdentifier="IBFirstResponder" id="8fS-aE-onr" sceneMemberID="firstResponder"/>
</objects>
@ -36,7 +33,7 @@
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<wkWebView opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="t8d-md-Yhc">
<rect key="frame" x="0.0" y="88" width="414" height="725"/>
<rect key="frame" x="0.0" y="44" width="414" height="769"/>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<wkWebViewConfiguration key="configuration">
<audiovisualMediaTypes key="mediaTypesRequiringUserActionForPlayback" none="YES"/>
@ -155,9 +152,6 @@
<rect key="frame" x="0.0" y="0.0" width="414" height="208"/>
<autoresizingMask key="autoresizingMask"/>
</tableViewCellContentView>
<connections>
<segue destination="vC3-pB-5Vb" kind="showDetail" identifier="showDetail" id="RT3-gH-cyN"/>
</connections>
</tableViewCell>
</prototypes>
<connections>
@ -206,7 +200,7 @@
<!--Feeds-->
<scene sceneID="smW-Zh-WAh">
<objects>
<tableViewController storyboardIdentifier="MasterViewController" useStoryboardIdentifierAsRestorationIdentifier="YES" clearsSelectionOnViewWillAppear="NO" id="7bK-jq-Zjz" customClass="MasterFeedViewController" customModule="NetNewsWire" customModuleProvider="target" sceneMemberID="viewController">
<tableViewController storyboardIdentifier="MasterFeedViewController" useStoryboardIdentifierAsRestorationIdentifier="YES" clearsSelectionOnViewWillAppear="NO" id="7bK-jq-Zjz" customClass="MasterFeedViewController" customModule="NetNewsWire" customModuleProvider="target" sceneMemberID="viewController">
<tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="grouped" separatorStyle="default" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="18" sectionFooterHeight="18" id="r7i-6Z-zg0">
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
@ -263,12 +257,8 @@
<autoresizingMask key="autoresizingMask"/>
</navigationBar>
<toolbar key="toolbar" opaque="NO" clearsContextBeforeDrawing="NO" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" id="Skn-vK-czG">
<rect key="frame" x="0.0" y="813" width="414" height="49"/>
<autoresizingMask key="autoresizingMask"/>
</toolbar>
<connections>
<segue destination="JEX-9P-axG" kind="relationship" relationship="rootViewController" id="GKi-kA-LjT"/>
</connections>
</navigationController>
<placeholder placeholderIdentifier="IBFirstResponder" id="SLD-UC-DBI" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
@ -284,7 +274,4 @@
<image name="square.and.arrow.up" catalog="system" width="56" height="64"/>
<image name="star" catalog="system" width="64" height="58"/>
</resources>
<inferredMetricsTieBreakers>
<segue reference="RT3-gH-cyN"/>
</inferredMetricsTieBreakers>
</document>

View File

@ -23,7 +23,7 @@ class DetailViewController: UIViewController {
@IBOutlet weak var browserBarButtonItem: UIBarButtonItem!
@IBOutlet weak var webView: WKWebView!
weak var coordinator: AppCoordinator?
weak var coordinator: AppCoordinator!
override func viewDidLoad() {
@ -47,14 +47,14 @@ class DetailViewController: UIViewController {
}
func markAsRead() {
if let article = coordinator?.currentArticle {
if let article = coordinator.currentArticle {
markArticles(Set([article]), statusKey: .read, flag: true)
}
}
func updateUI() {
guard let article = coordinator?.currentArticle else {
guard let article = coordinator.currentArticle else {
nextUnreadBarButtonItem.isEnabled = false
prevArticleBarButtonItem.isEnabled = false
nextArticleBarButtonItem.isEnabled = false
@ -65,9 +65,9 @@ class DetailViewController: UIViewController {
return
}
nextUnreadBarButtonItem.isEnabled = coordinator?.isAnyUnreadAvailable ?? false
prevArticleBarButtonItem.isEnabled = coordinator?.isPrevArticleAvailable ?? false
nextArticleBarButtonItem.isEnabled = coordinator?.isNextArticleAvailable ?? false
nextUnreadBarButtonItem.isEnabled = coordinator.isAnyUnreadAvailable
prevArticleBarButtonItem.isEnabled = coordinator.isPrevArticleAvailable
nextArticleBarButtonItem.isEnabled = coordinator.isNextArticleAvailable
readBarButtonItem.isEnabled = true
starBarButtonItem.isEnabled = true
@ -80,7 +80,7 @@ class DetailViewController: UIViewController {
let starImage = article.status.starred ? AppAssets.starClosedImage : AppAssets.starOpenImage
starBarButtonItem.image = starImage
if let timelineName = coordinator?.timelineName {
if let timelineName = coordinator.timelineName {
if navigationController?.navigationItem.backBarButtonItem?.title != timelineName {
let backItem = UIBarButtonItem(title: timelineName, style: .plain, target: nil, action: nil)
navigationController?.navigationItem.backBarButtonItem = backItem
@ -91,7 +91,7 @@ class DetailViewController: UIViewController {
func reloadHTML() {
guard let article = coordinator?.currentArticle, let webView = webView else {
guard let article = coordinator.currentArticle, let webView = webView else {
return
}
let style = ArticleStylesManager.shared.currentStyle
@ -110,7 +110,7 @@ class DetailViewController: UIViewController {
guard let articles = note.userInfo?[Account.UserInfoKey.articles] as? Set<Article> else {
return
}
if articles.count == 1 && articles.first?.articleID == coordinator?.currentArticle?.articleID {
if articles.count == 1 && articles.first?.articleID == coordinator.currentArticle?.articleID {
updateUI()
}
}
@ -132,41 +132,41 @@ class DetailViewController: UIViewController {
// MARK: Actions
@IBAction func nextUnread(_ sender: Any) {
coordinator?.selectNextUnread()
coordinator.selectNextUnread()
}
@IBAction func prevArticle(_ sender: Any) {
coordinator?.currentArticleIndexPath = coordinator?.prevArticleIndexPath
coordinator.currentArticleIndexPath = coordinator.prevArticleIndexPath
}
@IBAction func nextArticle(_ sender: Any) {
coordinator?.currentArticleIndexPath = coordinator?.nextArticleIndexPath
coordinator.currentArticleIndexPath = coordinator.nextArticleIndexPath
}
@IBAction func toggleRead(_ sender: Any) {
if let article = coordinator?.currentArticle {
if let article = coordinator.currentArticle {
markArticles(Set([article]), statusKey: .read, flag: !article.status.read)
}
}
@IBAction func toggleStar(_ sender: Any) {
if let article = coordinator?.currentArticle {
if let article = coordinator.currentArticle {
markArticles(Set([article]), statusKey: .starred, flag: !article.status.starred)
}
}
@IBAction func openBrowser(_ sender: Any) {
guard let preferredLink = coordinator?.currentArticle?.preferredLink, let url = URL(string: preferredLink) else {
guard let preferredLink = coordinator.currentArticle?.preferredLink, let url = URL(string: preferredLink) else {
return
}
UIApplication.shared.open(url, options: [:])
}
@IBAction func showActivityDialog(_ sender: Any) {
guard let preferredLink = coordinator?.currentArticle?.preferredLink, let url = URL(string: preferredLink) else {
guard let preferredLink = coordinator.currentArticle?.preferredLink, let url = URL(string: preferredLink) else {
return
}
let itemSource = ArticleActivityItemSource(url: url, subject: coordinator?.currentArticle?.title)
let itemSource = ArticleActivityItemSource(url: url, subject: coordinator.currentArticle?.title)
let activityViewController = UIActivityViewController(activityItems: [itemSource], applicationActivities: nil)
activityViewController.popoverPresentationController?.barButtonItem = self.actionBarButtonItem

View File

@ -276,12 +276,7 @@ class MasterFeedViewController: ProgressTableViewController, UndoableCommandRunn
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let timeline = UIStoryboard.main.instantiateController(ofType: MasterTimelineViewController.self)
timeline.coordinator = coordinator
coordinator.currentMasterIndexPath = indexPath
self.navigationController?.pushViewController(timeline, animated: true)
coordinator.didSelectFeed(indexPath)
}
override func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool {

View File

@ -63,16 +63,6 @@ class MasterTimelineViewController: ProgressTableViewController, UndoableCommand
resignFirstResponder()
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "showDetail" {
let controller = (segue.destination as! UINavigationController).topViewController as! DetailViewController
controller.coordinator = coordinator
controller.navigationItem.leftBarButtonItem = splitViewController?.displayModeButtonItem
controller.navigationItem.leftItemsSupplementBackButton = true
splitViewController?.toggleMasterView()
}
}
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
super.traitCollectionDidChange(previousTraitCollection)
@ -185,7 +175,7 @@ class MasterTimelineViewController: ProgressTableViewController, UndoableCommand
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
coordinator.currentArticleIndexPath = indexPath
coordinator.didSelectArticle(indexPath)
}
// MARK: Notifications

View File

@ -19,19 +19,8 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
window!.tintColor = AppAssets.netNewsWireBlueColor
window!.rootViewController = coordinator.start()
let splitViewController = UIStoryboard.main.instantiateInitialViewController() as! UISplitViewController
splitViewController.delegate = coordinator
window!.rootViewController = splitViewController
let masterNavigationController = splitViewController.viewControllers[0] as! UINavigationController
let masterFeedViewController = masterNavigationController.topViewController as! MasterFeedViewController
masterFeedViewController.coordinator = coordinator
let navigationController = splitViewController.viewControllers[splitViewController.viewControllers.count-1] as! UINavigationController
navigationController.topViewController!.navigationItem.leftBarButtonItem = splitViewController.displayModeButtonItem
// if let userActivity = connectionOptions.userActivities.first ?? session.stateRestorationActivity {
// if !configure(window: window, with: userActivity) {
// print("Failed to restore from \(userActivity)")