git.iko.soy/dashared/GDproject
on master help sign in
started working on coordinators.
commit3b1db6e787451b865f192a11bda37b1cfe2ab16c authorDarya Rednikina <rednikina.com@yandex.ru> dateSat 23 Feb 2019, 13:17 (8 years ago) parent478c049
10 files changed+171−32
GDproject.xcodeproj/project.pbxproj+20 GDproject/Base.lproj/Main.storyboard+14−1 GDproject/Controller/ News and channels/ChannelListController.swift+7−9 GDproject/Controller/ News and channels/ChannelsCoordinator.swift+53 GDproject/Controller/ News and channels/NewsController.swift+15−15 GDproject/Controller/ News and channels/NewsVC.swift+1−1 GDproject/Controller/Coordinator tab bar?/TabBarController.swift+28 GDproject/Controller/Coordinator tab bar?/TabbarView.swift+7 GDproject/Extentions.swift+14 GDproject/Supporting files/AppDelegate.swift+12−6
GDproject.xcodeproj/project.pbxproj+20
@@ -13,6 +13,9 @@
1313 125BD57F22171D73008A3575 /* Extentions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 125BD57E22171D73008A3575 /* Extentions.swift */; };
1414 125BD5812217314A008A3575 /* NewsVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 125BD5802217314A008A3575 /* NewsVC.swift */; };
1515 1288B5CE221F1158002BE6B1 /* DataStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1288B5CD221F1158002BE6B1 /* DataStorage.swift */; };
16+ 1291BE2D2221312D009D3F23 /* ChannelsCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1291BE2C2221312C009D3F23 /* ChannelsCoordinator.swift */; };
17+ 1291BE2F222152E1009D3F23 /* TabBarController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1291BE2E222152E1009D3F23 /* TabBarController.swift */; };
18+ 1291BE312221530D009D3F23 /* TabbarView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1291BE302221530D009D3F23 /* TabbarView.swift */; };
1619 12D7D133221C321600B35452 /* ChannelListController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12D7D132221C321600B35452 /* ChannelListController.swift */; };
1720 12D7D135221C42B700B35452 /* ChannelController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12D7D134221C42B700B35452 /* ChannelController.swift */; };
1821 12D7D137221D78E800B35452 /* Channel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12D7D136221D78E800B35452 /* Channel.swift */; };
@@ -70,6 +73,9 @@
7073 125BD57E22171D73008A3575 /* Extentions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Extentions.swift; sourceTree = "<group>"; };
7174 125BD5802217314A008A3575 /* NewsVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewsVC.swift; sourceTree = "<group>"; };
7275 1288B5CD221F1158002BE6B1 /* DataStorage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DataStorage.swift; sourceTree = "<group>"; };
76+ 1291BE2C2221312C009D3F23 /* ChannelsCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChannelsCoordinator.swift; sourceTree = "<group>"; };
77+ 1291BE2E222152E1009D3F23 /* TabBarController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabBarController.swift; sourceTree = "<group>"; };
78+ 1291BE302221530D009D3F23 /* TabbarView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabbarView.swift; sourceTree = "<group>"; };
7379 12D7D132221C321600B35452 /* ChannelListController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChannelListController.swift; sourceTree = "<group>"; };
7480 12D7D134221C42B700B35452 /* ChannelController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChannelController.swift; sourceTree = "<group>"; };
7581 12D7D136221D78E800B35452 /* Channel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Channel.swift; sourceTree = "<group>"; };
@@ -128,6 +134,15 @@
128134 path = Profile;
129135 sourceTree = "<group>";
130136 };
137+ 1291BE32222154C3009D3F23 /* Coordinator tab bar? */ = {
138+ isa = PBXGroup;
139+ children = (
140+ 1291BE2E222152E1009D3F23 /* TabBarController.swift */,
141+ 1291BE302221530D009D3F23 /* TabbarView.swift */,
142+ );
143+ path = "Coordinator tab bar?";
144+ sourceTree = "<group>";
145+ };
131146 12E36D8F221424EA006FCDD7 = {
132147 isa = PBXGroup;
133148 children = (
@@ -190,6 +205,7 @@
190205 12E36DCF22145923006FCDD7 /* Controller */ = {
191206 isa = PBXGroup;
192207 children = (
208+ 1291BE32222154C3009D3F23 /* Coordinator tab bar? */,
193209 123E37A4221F1B3200F6E42A /* LogInViewController.swift */,
194210 1288B5CC221F0EFE002BE6B1 /* Profile */,
195211 12E36DD322156519006FCDD7 /* News and channels */,
@@ -205,6 +221,7 @@
205221 12E36DC922144635006FCDD7 /* NewPostViewController.swift */,
206222 12E36DD022148122006FCDD7 /* FullPostController.swift */,
207223 12E36D9D221424EA006FCDD7 /* NewsController.swift */,
224+ 1291BE2C2221312C009D3F23 /* ChannelsCoordinator.swift */,
208225 125BD5802217314A008A3575 /* NewsVC.swift */,
209226 12E36DCB22144725006FCDD7 /* PostViewCell.swift */,
210227 );
@@ -302,11 +319,14 @@
302319 123E37A5221F1B3200F6E42A /* LogInViewController.swift in Sources */,
303320 125BD57F22171D73008A3575 /* Extentions.swift in Sources */,
304321 12D7D133221C321600B35452 /* ChannelListController.swift in Sources */,
322+ 1291BE312221530D009D3F23 /* TabbarView.swift in Sources */,
323+ 1291BE2D2221312D009D3F23 /* ChannelsCoordinator.swift in Sources */,
305324 12E36DD122148122006FCDD7 /* FullPostController.swift in Sources */,
306325 1288B5CE221F1158002BE6B1 /* DataStorage.swift in Sources */,
307326 125BD57D22171D2A008A3575 /* ProfileViewController.swift in Sources */,
308327 12DB7FDB2218590C0096878E /* InfoCell.swift in Sources */,
309328 12DB7FD922181E660096878E /* BasicInfoCell.swift in Sources */,
329+ 1291BE2F222152E1009D3F23 /* TabBarController.swift in Sources */,
310330 12D7D135221C42B700B35452 /* ChannelController.swift in Sources */,
311331 12E36D9C221424EA006FCDD7 /* AppDelegate.swift in Sources */,
312332 12DB7FD722181CD20096878E /* BasicInfoController.swift in Sources */,
GDproject/Base.lproj/Main.storyboard+14−1
@@ -1,5 +1,5 @@
11<?xml version="1.0" encoding="UTF-8"?>
2−<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="14460.31" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="IeP-4W-8LT">
2+<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="14460.31" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="609-2j-gc9">
33 <device id="retina4_7" orientation="portrait">
44 <adaptation id="fullscreen"/>
55 </device>
@@ -462,6 +462,19 @@
462462 </objects>
463463 <point key="canvasLocation" x="1089" y="958"/>
464464 </scene>
465+ <!--Navigation Controller-->
466+ <scene sceneID="r0M-xH-UwU">
467+ <objects>
468+ <navigationController id="609-2j-gc9" sceneMemberID="viewController">
469+ <navigationBar key="navigationBar" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" id="Ah8-NU-AsD">
470+ <rect key="frame" x="0.0" y="20" width="375" height="44"/>
471+ <autoresizingMask key="autoresizingMask"/>
472+ </navigationBar>
473+ </navigationController>
474+ <placeholder placeholderIdentifier="IBFirstResponder" id="Raj-78-jlT" userLabel="First Responder" sceneMemberID="firstResponder"/>
475+ </objects>
476+ <point key="canvasLocation" x="-2242" y="68"/>
477+ </scene>
465478 <!--Tab Bar Controller-->
466479 <scene sceneID="HCR-WO-p7g">
467480 <objects>
GDproject/Controller/ News and channels/ChannelListController.swift+7−9
@@ -16,8 +16,10 @@ struct ChannelData{
1616// TODO: make search controller availiable
1717class ChannelListController: UITableViewController, DataDelegate {
1818
19− // MARK:- filter search controller
19+ // MARK: - Output -
20+ var onChannelSelected: ((Channel) -> Void)?
2021
22+ // MARK:- filter search controller
2123 var filteredDataSource = [Channel]()
2224
2325 var myProtocol: DataDelegate?
@@ -40,10 +42,7 @@ class ChannelListController: UITableViewController, DataDelegate {
4042 }
4143
4244 func passData(for row: Int, channel: Channel) {
43− ChannelListController.dataSource[row].hashtags = channel.hashtags
44− ChannelListController.dataSource[row].people = channel.people
45− ChannelListController.dataSource[row].title = channel.title
46− ChannelListController.dataSource[row].subtitle = channel.subtitle
45+ ChannelListController.dataSource[row] = channel
4746 }
4847
4948 var searchController = UISearchController(searchResultsController: nil)
@@ -154,14 +153,13 @@ class ChannelListController: UITableViewController, DataDelegate {
154153 return [editButton, deleteButton]
155154 }
156155
156+ // TODO: remove popping
157157 override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
158158 {
159159 if isFiltering {
160− navigationController?.popViewController(animated: true)
161− myProtocol?.passData(for: 0, channel: filteredDataSource[indexPath.row])
160+ onChannelSelected?(filteredDataSource[indexPath.row])
162161 } else {
163− navigationController?.popViewController(animated: true)
164− myProtocol?.passData(for: 0, channel: ChannelListController.dataSource[indexPath.row])
162+ onChannelSelected?(ChannelListController.dataSource[indexPath.row])
165163 }
166164 }
167165}
GDproject/Controller/ News and channels/ChannelsCoordinator.swiftnew file+53
@@ -0,0 +1,53 @@
1+//
2+// ChannelsCoordinator.swift
3+// GDproject
4+//
5+// Created by cstore on 23/02/2019.
6+// Copyright © 2019 drHSE. All rights reserved.
7+//
8+
9+import Foundation
10+import UIKit
11+
12+final class ChannelsCoordinator{
13+
14+ // MARK: - Properties
15+ private var channel: Channel { didSet { updateInterfaces() } }
16+ private weak var navigationController: UINavigationController?
17+
18+ // MARK:- Init
19+ init(currentChannel: Channel, navigationController: UINavigationController) {
20+ self.channel = currentChannel
21+ self.navigationController = navigationController
22+ }
23+
24+ func start(){
25+ showCurrentChannel()
26+ }
27+
28+ // MARK: - Private implementation
29+ private func showListOfChannels(){
30+ let controller = UIStoryboard.makeChannelsListController()
31+ controller.onChannelSelected = { [weak self] channel
32+ in
33+ self?.channel = channel
34+ _ = self?.navigationController?.popViewController(animated: true)
35+ }
36+ navigationController?.pushViewController(controller, animated: true)
37+ }
38+
39+ private func showCurrentChannel(){
40+ let controller = UIStoryboard.makeNewsController()
41+ controller.channel = channel
42+ controller.onSelectChannel = { [weak self] in
43+ self?.showListOfChannels()
44+ }
45+ navigationController?.pushViewController(controller, animated: false)
46+ }
47+ // MARK:- update only viewControllers which are depandable on chosen channel
48+ private func updateInterfaces() {
49+ navigationController?.viewControllers.forEach {
50+ ($0 as? UpdateableWithChannel)?.channel = channel
51+ }
52+ }
53+}
GDproject/Controller/ News and channels/NewsController.swift+15−15
@@ -10,26 +10,27 @@ import UIKit
1010import TinyConstraints
1111import Cartography
1212
13−
13+protocol UpdateableWithChannel: class {
14+ var channel: Channel? { get set }
15+}
1416protocol NewPostDelegate {
1517 func addPost(post: Post)
1618}
1719
1820// MARK:- Controller with posts and channels availiable.
1921// Search is availiable within every table (posts and channels). Has button-functionality for boths post and chnnels
20−class NewsController: UITableViewController, UISearchControllerDelegate, DataDelegate, NewPostDelegate
22+class NewsController: UITableViewController, UISearchControllerDelegate, NewPostDelegate, UpdateableWithChannel
2123{
22− var currentChannel: Channel?{
24+ var channel: Channel?{
2325 didSet{
24− news.dataSourse = currentChannel?.posts ?? []
25− navigationItem.title = currentChannel?.title ?? ""
26+ news.dataSourse = channel?.posts ?? []
27+ navigationItem.title = channel?.title ?? ""
2628 }
2729 }
2830
29− func passData(for row: Int, channel: Channel) {
30− currentChannel = channel
31− }
32−
31+ // MARK: - Output -
32+ var onSelectChannel: (() -> Void)?
33+
3334 func addPost(post: Post) {
3435 news.dataSourse.insert(post, at: 0)
3536 }
@@ -72,7 +73,7 @@ class NewsController: UITableViewController, UISearchControllerDelegate, DataDe
7273 super.viewDidLoad()
7374
7475 //view.backgroundColor = .white
75− currentChannel = ChannelListController.dataSource[0]
76+ channel = ChannelListController.dataSource[0]
7677
7778 view.addSubview(label)
7879 //label.horizontalToSuperview(insets: .left(30) + .right(30))
@@ -84,7 +85,7 @@ class NewsController: UITableViewController, UISearchControllerDelegate, DataDe
8485 searchController.delegate = self
8586 searchController.obscuresBackgroundDuringPresentation = false
8687
87− news.dataSourse = currentChannel!.posts
88+ news.dataSourse = channel!.posts
8889 news.viewController = self
8990
9091
@@ -163,7 +164,7 @@ class NewsController: UITableViewController, UISearchControllerDelegate, DataDe
163164 super.viewWillAppear(animated)
164165 print("hello")
165166 navigationController?.navigationBar.prefersLargeTitles = true
166− if currentChannel!.posts.isEmpty {
167+ if channel!.posts.isEmpty {
167168 //tableView.isHidden = true
168169 label.isHidden = false
169170 } else {
@@ -182,10 +183,9 @@ class NewsController: UITableViewController, UISearchControllerDelegate, DataDe
182183 tableView.reloadData()
183184 }
184185
186+ // MARK:- attempt with coordinator
185187 @objc func showChannels(_ barItem: UIBarButtonItem){
186− let vc = storyboard!.instantiateViewController(withIdentifier: channelListControllerId) as! ChannelListController
187− vc.myProtocol = self
188− self.navigationController!.pushViewController(vc, animated: true)
188+ onSelectChannel?()
189189 }
190190
191191 @objc func writePost(_ barItem: UIBarButtonItem)
GDproject/Controller/ News and channels/NewsVC.swift+1−1
@@ -32,7 +32,7 @@ class NewsVC: UIViewController, UITableViewDelegate, UITableViewDataSource{
3232 }
3333 else if indexPath.section == 0 && type == .NEWS{
3434 let vc = viewController!.storyboard!.instantiateViewController(withIdentifier: channelListControllerId) as! ChannelListController
35− vc.myProtocol = viewController as? NewsController
35+ //vc.myProtocol = viewController as? NewsController
3636 viewController!.navigationController!.pushViewController(vc, animated: true)
3737 }
3838 }
GDproject/Controller/Coordinator tab bar?/TabBarController.swiftnew file+28
@@ -0,0 +1,28 @@
1+import UIKit
2+
3+final class TabbarController: UITabBarController, UITabBarControllerDelegate, TabbarView {
4+
5+ var onItemFlowSelect: ((UINavigationController) -> ())?
6+ var onSettingsFlowSelect: ((UINavigationController) -> ())?
7+ var onViewDidLoad: ((UINavigationController) -> ())?
8+
9+ override func viewDidLoad() {
10+ super.viewDidLoad()
11+
12+ delegate = self
13+ if let controller = customizableViewControllers?.first as? UINavigationController {
14+ onViewDidLoad?(controller)
15+ }
16+ }
17+
18+ func tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController) {
19+ guard let controller = viewControllers?[selectedIndex] as? UINavigationController else { return }
20+
21+ if selectedIndex == 0 {
22+ onItemFlowSelect?(controller)
23+ }
24+ else if selectedIndex == 1 {
25+ onSettingsFlowSelect?(controller)
26+ }
27+ }
28+}
GDproject/Controller/Coordinator tab bar?/TabbarView.swiftnew file+7
@@ -0,0 +1,7 @@
1+import UIKit
2+
3+protocol TabbarView: class {
4+ var onItemFlowSelect: ((UINavigationController) -> ())? { get set }
5+ var onSettingsFlowSelect: ((UINavigationController) -> ())? { get set }
6+ var onViewDidLoad: ((UINavigationController) -> ())? { get set }
7+}
GDproject/Extentions.swift+14
@@ -34,3 +34,17 @@ extension UIView
3434 addConstraints(NSLayoutConstraint.constraints(withVisualFormat: format, options: NSLayoutConstraint.FormatOptions(), metrics: nil, views: viewsDictionary))
3535 }
3636}
37+
38+
39+extension UIStoryboard {
40+
41+ private static let userEdit = UIStoryboard(name: "Main", bundle: nil)
42+
43+ class func makeChannelsListController() -> ChannelListController {
44+ return UIStoryboard.userEdit.instantiateViewController(withIdentifier: channelListControllerId) as! ChannelListController
45+ }
46+
47+ class func makeNewsController() -> NewsController {
48+ return UIStoryboard.userEdit.instantiateViewController(withIdentifier: newsController) as! NewsController
49+ }
50+}
GDproject/Supporting files/AppDelegate.swift+12−6
@@ -11,14 +11,20 @@ import UIKit
1111@UIApplicationMain
1212class AppDelegate: UIResponder, UIApplicationDelegate {
1313
14+ var coordinator: ChannelsCoordinator!
1415 var window: UIWindow?
16+ var rootController: UINavigationController {
17+ return self.window!.rootViewController as! UINavigationController
18+ }
1519
16−
17− func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
18− // Override point for customization after application launch.
19−// window = UIWindow(frame: UIScreen.main.bounds)
20−// window?.makeKeyAndVisible()
21−// window?.rootViewController = MainController()
20+ private func makeCoordinator(with: UINavigationController) -> ChannelsCoordinator {
21+ return ChannelsCoordinator(currentChannel: Channel(title: "example", subtitle: "ex", hashtags: ["none"], people: ["none"], posts: []), navigationController: rootController)
22+ }
23+
24+ func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool
25+ {
26+ coordinator = makeCoordinator(with: rootController)
27+ coordinator.start()
2228 return true
2329 }
2430