git.iko.soy/dashared/GDproject
on master help sign in
channels are completed. needs minor modifications
daecc84Darya Rednikina
GDproject/Base.lproj/Main.storyboard+1−1
@@ -14,7 +14,7 @@
14 <!--News Controller-->
14 <!--News Controller-->
15 <scene sceneID="tne-QT-ifu">
15 <scene sceneID="tne-QT-ifu">
16 <objects>
16 <objects>
17− <viewController id="BYZ-38-t0r" customClass="NewsController" customModule="GDproject" customModuleProvider="target" sceneMemberID="viewController">
17+ <viewController storyboardIdentifier="NewsController" id="BYZ-38-t0r" customClass="NewsController" customModule="GDproject" customModuleProvider="target" sceneMemberID="viewController">
18 <view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
18 <view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
19 <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
19 <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
20 <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
20 <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
GDproject/Constants.swift+2
@@ -26,3 +26,5 @@ let channelListControllerId = "ChannelListController"
26let itemCellId = "ItemCell"
26let itemCellId = "ItemCell"
27
27
28let channelControllerId = "ChannelController"
28let channelControllerId = "ChannelController"
29+
30+let newsController = "NewsController"
GDproject/Controller/ChannelController.swift+3−1
@@ -68,8 +68,10 @@ class ChannelController: UIViewController, UITableViewDelegate, UITableViewDataS
68 switch searchBar.selectedScopeButtonIndex{
68 switch searchBar.selectedScopeButtonIndex{
69 case 0:
69 case 0:
70 channel?.people.append(dataSource[indexPath.row])
70 channel?.people.append(dataSource[indexPath.row])
71+ print("people = \(channel!.people)")
71 case 1:
72 case 1:
72 channel?.hashtags.append(dataSource[indexPath.row])
73 channel?.hashtags.append(dataSource[indexPath.row])
74+ print("hashtags = \(channel!.hashtags)")
73 default:
75 default:
74 break
76 break
75 }
77 }
@@ -85,7 +87,7 @@ class ChannelController: UIViewController, UITableViewDelegate, UITableViewDataS
85 })
87 })
86 // TODO: dataPass
88 // TODO: dataPass
87 case 1:
89 case 1:
88− channel?.hashtags = channel!.people.filter({ (s) -> Bool in
90+ channel?.hashtags = channel!.hashtags.filter({ (s) -> Bool in
89 !fullTags[indexPath.row].contains(s)
91 !fullTags[indexPath.row].contains(s)
90 })
92 })
91 // TODO: dataPass
93 // TODO: dataPass
GDproject/Controller/ChannelListController.swift+64−9
@@ -16,6 +16,28 @@ struct ChannelData{
16// TODO: make search controller availiable
16// TODO: make search controller availiable
17class ChannelListController: UITableViewController, DataDelegate {
17class ChannelListController: UITableViewController, DataDelegate {
18
18
19+ // MARK:- filter search controller
20+
21+ var filteredDataSource = [Channel]()
22+ var myProtocol: DataDelegate?
23+
24+ var isFiltering: Bool {
25+ return searchController.isActive && !searchBarIsEmpty()
26+ }
27+
28+ func searchBarIsEmpty() -> Bool {
29+ return searchController.searchBar.text?.isEmpty ?? true
30+ }
31+
32+ func filterContentForSearchText(_ searchText: String, scope: String = "All")
33+ {
34+ filteredDataSource = ChannelListController.dataSource.filter({(keys : Channel) -> Bool in
35+ return keys.title.lowercased().contains(searchText.lowercased())
36+ })
37+
38+ tableView.reloadData()
39+ }
40+
19 func passData(for row: Int, channel: Channel) {
41 func passData(for row: Int, channel: Channel) {
20 ChannelListController.dataSource[row].hashtags = channel.hashtags
42 ChannelListController.dataSource[row].hashtags = channel.hashtags
21 ChannelListController.dataSource[row].people = channel.people
43 ChannelListController.dataSource[row].people = channel.people
@@ -29,8 +51,8 @@ class ChannelListController: UITableViewController, DataDelegate {
29 super.viewDidLoad()
51 super.viewDidLoad()
30 setUpNavigationBar()
52 setUpNavigationBar()
31 navigationItem.title = "Channels"
53 navigationItem.title = "Channels"
32−
54+ searchController.obscuresBackgroundDuringPresentation = false
33− searchController.searchBar.placeholder = "Search anything"
55+ searchController.searchBar.placeholder = "Search channel"
34 navigationItem.searchController = searchController
56 navigationItem.searchController = searchController
35 }
57 }
36
58
@@ -48,7 +70,7 @@ class ChannelListController: UITableViewController, DataDelegate {
48 {
70 {
49 // insertion
71 // insertion
50 tableView.beginUpdates()
72 tableView.beginUpdates()
51− ChannelListController.dataSource.insert(Channel(title: "Untitled", subtitle: "No", hashtags: [], people: []), at: 0)
73+ ChannelListController.dataSource.insert(Channel(title: "Untitled", subtitle: "No", hashtags: [], people: [], posts: []), at: 0)
52 tableView.insertRows(at: [IndexPath(row: 0, section: 0)], with: .none)
74 tableView.insertRows(at: [IndexPath(row: 0, section: 0)], with: .none)
53 tableView.endUpdates()
75 tableView.endUpdates()
54
76
@@ -61,22 +83,37 @@ class ChannelListController: UITableViewController, DataDelegate {
61 }
83 }
62
84
63 static var dataSource : [Channel] = [
85 static var dataSource : [Channel] = [
64− Channel(title: "Title", subtitle: "subtitle", hashtags: ["# sad", "# happy"], people: ["Seva", "Andrey"]),
86+ Channel(title: "Title", subtitle: "subtitle", hashtags: ["# sad", "# happy"], people: ["Seva", "Andrey"], posts: [Post(dataArray: [.text("Le Lorem Ipsum est simplement du faux texte employé dans la composition et la mise en page avant impression. Le Lorem Ipsum est le faux texte standard.")], from: User(name: "vbogomazova", id: 2, fullName: "Богомазова Вероника Львовна"), date: "14.02.19 в 12:05")]),
65− Channel(title: "Title2", subtitle: "subtitle2", hashtags: ["# studyhard", "# university"], people: ["Pasha", "Olya", "Andrey", "Ilya"]),
87+ Channel(title: "Title2", subtitle: "subtitle2", hashtags: ["# studyhard", "# university"], people: ["Pasha", "Olya", "Andrey", "Ilya"], posts:
66− Channel(title: "Title3", subtitle: "subtitle3", hashtags: ["# lol", "# meme", "# hehe"], people: ["Superman"])
88+ [
89+ Post(dataArray: [.text("L'avantage du Lorem Ipsum sur un texte générique comme 'Du texte. Du texte. Du texte.' est qu'il possède une distribution de lettres plus ou moins normale.")], from: User(name: "vbogomazova", id: 2, fullName: "Богомазова Вероника Львовна"), date: "14.02.19 в 12:05"),
90+ Post(dataArray: [.text("par accident, souvent intentionnellement (histoire d'y rajouter de petits clins d'oeil, voire des phrases embarassantes).")], from: User(name: "vbogomazova", id: 2, fullName: "Богомазова Вероника Львовна"), date: "14.02.19 в 12:05")
91+ ]),
92+ Channel(title: "Title3", subtitle: "subtitle3", hashtags: ["# lol", "# meme", "# hehe"], people: ["Superman"], posts: [Post(dataArray: [.text("Ipsum est le faux texte standard de l'imprimerie depuis les années 1500, quand un imprimeur anonyme assembla ensemble des morceaux de texte pour réaliser un livre spécimen de polices de texte. Il n'a pas fait que survivre cinq siècles, mais s'est aussi adapté à la bureautique informatique, sans que son contenu n'en soit modifié.")], from: User(name: "vbogomazova", id: 2, fullName: "Богомазова Вероника Львовна"), date: "14.02.19 в 12:05")])
67 ]
93 ]
68
94
69 override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
95 override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
96+ if isFiltering {
97+ return filteredDataSource.count
98+ } else {
70− return ChannelListController.dataSource.count
99+ return ChannelListController.dataSource.count
100+ }
71 }
101 }
72
102
73 override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
103 override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
74 {
104 {
105+
75 let cell = tableView.dequeueReusableCell(withIdentifier: channelCellId, for: indexPath)
106 let cell = tableView.dequeueReusableCell(withIdentifier: channelCellId, for: indexPath)
76− cell.textLabel?.text = ChannelListController.dataSource[indexPath.row].title
77− cell.detailTextLabel?.text = ChannelListController.dataSource[indexPath.row].subtitle
78
107
79
108
109+ if isFiltering{
110+ cell.textLabel?.text = filteredDataSource[indexPath.row].title
111+ cell.detailTextLabel?.text = filteredDataSource[indexPath.row].subtitle
112+ } else {
113+ cell.textLabel?.text = ChannelListController.dataSource[indexPath.row].title
114+ cell.detailTextLabel?.text = ChannelListController.dataSource[indexPath.row].subtitle
115+ }
116+
80 return cell
117 return cell
81 }
118 }
82
119
@@ -109,4 +146,22 @@ class ChannelListController: UITableViewController, DataDelegate {
109
146
110 return [editButton, deleteButton]
147 return [editButton, deleteButton]
111 }
148 }
149+
150+ override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
151+ {
152+ if isFiltering {
153+ navigationController?.popViewController(animated: true)
154+ myProtocol?.passData(for: 0, channel: filteredDataSource[indexPath.row])
155+ } else {
156+ navigationController?.popViewController(animated: true)
157+ myProtocol?.passData(for: 0, channel: ChannelListController.dataSource[indexPath.row])
158+ }
159+ }
160+}
161+
162+
163+extension ChannelListController : UISearchResultsUpdating {
164+ func updateSearchResults(for searchController: UISearchController) {
165+ filterContentForSearchText(searchController.searchBar.text!)
166+ }
112}
167}
GDproject/Controller/News/NewPostViewController.swift+15−17
@@ -18,6 +18,7 @@ class NewPostViewController: UIViewController, UITextViewDelegate {
18 let textStorage = MarklightTextStorage()
18 let textStorage = MarklightTextStorage()
19
19
20 weak var parentVC: NewsController?
20 weak var parentVC: NewsController?
21+ var myProtocol: NewPostDelegate?
21
22
22 static var draft: String = ""
23 static var draft: String = ""
23 var textView: UITextView!
24 var textView: UITextView!
@@ -110,13 +111,13 @@ class NewPostViewController: UIViewController, UITextViewDelegate {
110 NotificationCenter.default.addObserver(self, selector: #selector(handleKeyboardNotifications), name: UIResponder.keyboardWillHideNotification, object: nil)
111 NotificationCenter.default.addObserver(self, selector: #selector(handleKeyboardNotifications), name: UIResponder.keyboardWillHideNotification, object: nil)
111
112
112 // Partial fixes to a long standing bug, to keep the caret inside the `UITextView` always visible
113 // Partial fixes to a long standing bug, to keep the caret inside the `UITextView` always visible
113− NotificationCenter.default.addObserver(forName: UITextView.textDidChangeNotification, object: textView, queue: OperationQueue.main) { (notification) -> Void in
114+ NotificationCenter.default.addObserver(forName: UITextView.textDidChangeNotification, object: textView, queue: OperationQueue.main) { [weak self] (notification) -> Void in
114− if self.textView.textStorage.string.hasSuffix("\n") {
115+ if self!.textView.textStorage.string.hasSuffix("\n") {
115 CATransaction.setCompletionBlock({ () -> Void in
116 CATransaction.setCompletionBlock({ () -> Void in
116− self.scrollToCaret(self.textView, animated: false)
117+ self!.scrollToCaret(self!.textView, animated: false)
117 })
118 })
118 } else {
119 } else {
119− self.scrollToCaret(self.textView, animated: false)
120+ self!.scrollToCaret(self!.textView, animated: false)
120 }
121 }
121 }
122 }
122
123
@@ -125,8 +126,11 @@ class NewPostViewController: UIViewController, UITextViewDelegate {
125 @objc func handleKeyboardNotifications(notification: NSNotification){
126 @objc func handleKeyboardNotifications(notification: NSNotification){
126 if let userInfo = notification.userInfo{
127 if let userInfo = notification.userInfo{
127 // UIKeyboardFrameEndUserInfoKey
128 // UIKeyboardFrameEndUserInfoKey
129+
128 let keyBoardFrame = (userInfo[UIResponder.keyboardFrameEndUserInfoKey] as! NSValue).cgRectValue
130 let keyBoardFrame = (userInfo[UIResponder.keyboardFrameEndUserInfoKey] as! NSValue).cgRectValue
131+
129− bottomTextViewConstraint?.constant = notification.name == UIResponder.keyboardWillShowNotification ? keyBoardFrame.height : 0
132+ bottomTextViewConstraint?.constant = notification.name == UIResponder.keyboardWillShowNotification ? keyBoardFrame.height - tabBarController!.tabBar.frame.height : 0
133+
130 print(bottomTextViewConstraint!.constant)
134 print(bottomTextViewConstraint!.constant)
131
135
132 UIView.animate(withDuration: 0, delay: 0, options: .curveEaseOut, animations: {
136 UIView.animate(withDuration: 0, delay: 0, options: .curveEaseOut, animations: {
@@ -188,12 +192,7 @@ class NewPostViewController: UIViewController, UITextViewDelegate {
188
192
189
193
190 // adding row to uiTableView after adding new post
194 // adding row to uiTableView after adding new post
191− guard let vc = parentVC else {return}
195+ myProtocol?.addPost(post: p)
192− vc.tableView.beginUpdates()
193− let indexPath1: IndexPath = IndexPath(row: 0, section: 0)
194− vc.dataSourse.insert(p, at: 0)
195− vc.tableView.insertRows(at: [indexPath1], with: .fade)
196− vc.tableView.endUpdates()
197 moveBackToParentVC()
196 moveBackToParentVC()
198 // somewhere here i will be sending server notifications about new post arrival
197 // somewhere here i will be sending server notifications about new post arrival
199 }
198 }
@@ -203,17 +202,18 @@ class NewPostViewController: UIViewController, UITextViewDelegate {
203
202
204 let saveAction = UIAlertAction(title: "Save draft", style: .default)
203 let saveAction = UIAlertAction(title: "Save draft", style: .default)
205 {
204 {
205+ [weak self]
206 _ in
206 _ in
207− NewPostViewController.draft = self.textView.text
207+ NewPostViewController.draft = self?.textView.text ?? ""
208− self.moveBackToParentVC()
208+ self?.moveBackToParentVC()
209 }
209 }
210
210
211 let deleteAction = UIAlertAction(title: "Delete draft", style: .destructive)
211 let deleteAction = UIAlertAction(title: "Delete draft", style: .destructive)
212 {
212 {
213− (_)
213+ [weak self] (_)
214 in
214 in
215 NewPostViewController.draft = ""
215 NewPostViewController.draft = ""
216− self.moveBackToParentVC()
216+ self?.moveBackToParentVC()
217 }
217 }
218
218
219 let cancelAction = UIAlertAction(title: "Cancel", style: .cancel)
219 let cancelAction = UIAlertAction(title: "Cancel", style: .cancel)
@@ -242,8 +242,6 @@ class NewPostViewController: UIViewController, UITextViewDelegate {
242 }
242 }
243
243
244
244
245−
246−
247 func textView(_ textView: UITextView, shouldInteractWith URL: URL, in characterRange: NSRange) -> Bool {
245 func textView(_ textView: UITextView, shouldInteractWith URL: URL, in characterRange: NSRange) -> Bool {
248 print("Should interact with: \(URL)")
246 print("Should interact with: \(URL)")
249 return true
247 return true
GDproject/Controller/News/NewsController.swift+16−2
@@ -10,11 +10,24 @@ import UIKit
10import TinyConstraints
10import TinyConstraints
11import Cartography
11import Cartography
12
12
13+
14+protocol NewPostDelegate {
15+ func addPost(post: Post)
16+}
17+
13// MARK:- Controller with posts and channels availiable.
18// MARK:- Controller with posts and channels availiable.
14// Search is availiable within every table (posts and channels). Has button-functionality for boths post and chnnels
19// Search is availiable within every table (posts and channels). Has button-functionality for boths post and chnnels
15−class NewsController: UIViewController, UISearchControllerDelegate, UITableViewDelegate, UITableViewDataSource
20+class NewsController: UIViewController, UISearchControllerDelegate, UITableViewDelegate, UITableViewDataSource, DataDelegate, NewPostDelegate
16{
21{
17
22
23+ func passData(for row: Int, channel: Channel) {
24+ news.dataSourse = channel.posts
25+ navigationItem.title = channel.title
26+ }
27+
28+ func addPost(post: Post) {
29+ news.dataSourse.insert(post, at: 0)
30+ }
18
31
19 var array = ["Faculty 1", "Faculty 2","Faculty 3","Faculty 4","Faculty 5","Faculty 6","Faculty 7","Faculty 8","Faculty 9","Faculty 10","Faculty 11","Faculty 12","Faculty 13","Faculty 14","Faculty 15","Faculty 16","Faculty 17","Faculty 18"]
32 var array = ["Faculty 1", "Faculty 2","Faculty 3","Faculty 4","Faculty 5","Faculty 6","Faculty 7","Faculty 8","Faculty 9","Faculty 10","Faculty 11","Faculty 12","Faculty 13","Faculty 14","Faculty 15","Faculty 16","Faculty 17","Faculty 18"]
20
33
@@ -128,6 +141,7 @@ class NewsController: UIViewController, UISearchControllerDelegate, UITableViewD
128 super.viewWillAppear(animated)
141 super.viewWillAppear(animated)
129 print("hello")
142 print("hello")
130 navigationController?.navigationBar.prefersLargeTitles = true
143 navigationController?.navigationBar.prefersLargeTitles = true
144+ tableView.reloadData()
131 }
145 }
132
146
133 func setUpNavigationItemsforPosts(){
147 func setUpNavigationItemsforPosts(){
@@ -147,7 +161,7 @@ class NewsController: UIViewController, UISearchControllerDelegate, UITableViewD
147 vc.navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Post", style: .plain, target: vc, action: #selector(vc.newPost))
161 vc.navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Post", style: .plain, target: vc, action: #selector(vc.newPost))
148 vc.navigationItem.leftBarButtonItem = UIBarButtonItem(title: "Close", style: .plain, target: vc, action: #selector(vc.closeView))
162 vc.navigationItem.leftBarButtonItem = UIBarButtonItem(title: "Close", style: .plain, target: vc, action: #selector(vc.closeView))
149
163
150− vc.parentVC = self
164+ vc.myProtocol = self
151
165
152 let transition = CATransition()
166 let transition = CATransition()
153 transition.duration = 0.5
167 transition.duration = 0.5
GDproject/Controller/News/NewsVC.swift+1−1
@@ -37,7 +37,7 @@ class NewsVC: UIViewController, UITableViewDelegate, UITableViewDataSource{
37 }
37 }
38 else if indexPath.section == 0 && type == .NEWS{
38 else if indexPath.section == 0 && type == .NEWS{
39 let vc = viewController!.storyboard!.instantiateViewController(withIdentifier: channelListControllerId) as! ChannelListController
39 let vc = viewController!.storyboard!.instantiateViewController(withIdentifier: channelListControllerId) as! ChannelListController
40−
40+ vc.myProtocol = viewController as? NewsController
41 viewController!.navigationController!.pushViewController(vc, animated: true)
41 viewController!.navigationController!.pushViewController(vc, animated: true)
42 }
42 }
43 }
43 }
GDproject/Simple model/Channel.swift+5−1
@@ -15,10 +15,14 @@ class Channel {
15 var hashtags: [String] = []
15 var hashtags: [String] = []
16 var people: [String] = []
16 var people: [String] = []
17
17
18+ var posts: [Post] = []
19+
18− init(title: String, subtitle: String, hashtags: [String], people: [String]) {
20+ init(title: String, subtitle: String, hashtags: [String], people: [String], posts: [Post])
21+ {
19 self.title = title
22 self.title = title
20 self.subtitle = subtitle
23 self.subtitle = subtitle
21 self.people = people
24 self.people = people
22 self.hashtags = hashtags
25 self.hashtags = hashtags
26+ self.posts = posts
23 }
27 }
24}
28}