git.iko.soy/dashared/GDproject
on master help sign in
Channels: pull request #3 from dashared/developer
f5ee61bDarya Rednikina
GDproject.xcodeproj/project.pbxproj+57−18
@@ -7,9 +7,17 @@
7 objects = {
7 objects = {
8
8
9/* Begin PBXBuildFile section */
9/* Begin PBXBuildFile section */
10+ 123E37A5221F1B3200F6E42A /* LogInViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 123E37A4221F1B3200F6E42A /* LogInViewController.swift */; };
11+ 123E37A7221F1DD700F6E42A /* MainController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 123E37A6221F1DD700F6E42A /* MainController.swift */; };
10 125BD57D22171D2A008A3575 /* ProfileViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 125BD57C22171D2A008A3575 /* ProfileViewController.swift */; };
12 125BD57D22171D2A008A3575 /* ProfileViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 125BD57C22171D2A008A3575 /* ProfileViewController.swift */; };
11 125BD57F22171D73008A3575 /* Extentions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 125BD57E22171D73008A3575 /* Extentions.swift */; };
13 125BD57F22171D73008A3575 /* Extentions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 125BD57E22171D73008A3575 /* Extentions.swift */; };
12 125BD5812217314A008A3575 /* NewsVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 125BD5802217314A008A3575 /* NewsVC.swift */; };
14 125BD5812217314A008A3575 /* NewsVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 125BD5802217314A008A3575 /* NewsVC.swift */; };
15+ 1288B5CE221F1158002BE6B1 /* DataStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1288B5CD221F1158002BE6B1 /* DataStorage.swift */; };
16+ 1291BE2D2221312D009D3F23 /* ChannelsCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1291BE2C2221312C009D3F23 /* ChannelsCoordinator.swift */; };
17+ 1291BE342221569B009D3F23 /* TabbarCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1291BE332221569B009D3F23 /* TabbarCoordinator.swift */; };
18+ 12D7D133221C321600B35452 /* ChannelListController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12D7D132221C321600B35452 /* ChannelListController.swift */; };
19+ 12D7D135221C42B700B35452 /* ChannelController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12D7D134221C42B700B35452 /* ChannelController.swift */; };
20+ 12D7D137221D78E800B35452 /* Channel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12D7D136221D78E800B35452 /* Channel.swift */; };
13 12DB7FD722181CD20096878E /* BasicInfoController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12DB7FD622181CD20096878E /* BasicInfoController.swift */; };
21 12DB7FD722181CD20096878E /* BasicInfoController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12DB7FD622181CD20096878E /* BasicInfoController.swift */; };
14 12DB7FD922181E660096878E /* BasicInfoCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12DB7FD822181E660096878E /* BasicInfoCell.swift */; };
22 12DB7FD922181E660096878E /* BasicInfoCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12DB7FD822181E660096878E /* BasicInfoCell.swift */; };
15 12DB7FDB2218590C0096878E /* InfoCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12DB7FDA2218590C0096878E /* InfoCell.swift */; };
23 12DB7FDB2218590C0096878E /* InfoCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12DB7FDA2218590C0096878E /* InfoCell.swift */; };
@@ -29,8 +37,6 @@
29 12E36DC0221441DB006FCDD7 /* Marklight.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 12E36DB222143D4E006FCDD7 /* Marklight.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
37 12E36DC0221441DB006FCDD7 /* Marklight.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 12E36DB222143D4E006FCDD7 /* Marklight.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
30 12E36DC2221441E1006FCDD7 /* MarkdownKit.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 12E36DB022143D47006FCDD7 /* MarkdownKit.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
38 12E36DC2221441E1006FCDD7 /* MarkdownKit.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 12E36DB022143D47006FCDD7 /* MarkdownKit.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
31 12E36DC4221441EA006FCDD7 /* Cartography.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 12E36DAE22143D40006FCDD7 /* Cartography.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
39 12E36DC4221441EA006FCDD7 /* Cartography.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 12E36DAE22143D40006FCDD7 /* Cartography.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
32− 12E36DC622144266006FCDD7 /* HeaderNewsChannels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12E36DC522144266006FCDD7 /* HeaderNewsChannels.swift */; };
33− 12E36DC822144374006FCDD7 /* ChannelsController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12E36DC722144374006FCDD7 /* ChannelsController.swift */; };
34 12E36DCA22144635006FCDD7 /* NewPostViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12E36DC922144635006FCDD7 /* NewPostViewController.swift */; };
40 12E36DCA22144635006FCDD7 /* NewPostViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12E36DC922144635006FCDD7 /* NewPostViewController.swift */; };
35 12E36DCC22144725006FCDD7 /* PostViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12E36DCB22144725006FCDD7 /* PostViewCell.swift */; };
41 12E36DCC22144725006FCDD7 /* PostViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12E36DCB22144725006FCDD7 /* PostViewCell.swift */; };
36 12E36DCE22144756006FCDD7 /* Constants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12E36DCD22144756006FCDD7 /* Constants.swift */; };
42 12E36DCE22144756006FCDD7 /* Constants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12E36DCD22144756006FCDD7 /* Constants.swift */; };
@@ -60,9 +66,17 @@
60/* End PBXCopyFilesBuildPhase section */
66/* End PBXCopyFilesBuildPhase section */
61
67
62/* Begin PBXFileReference section */
68/* Begin PBXFileReference section */
69+ 123E37A4221F1B3200F6E42A /* LogInViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LogInViewController.swift; sourceTree = "<group>"; };
70+ 123E37A6221F1DD700F6E42A /* MainController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainController.swift; sourceTree = "<group>"; };
63 125BD57C22171D2A008A3575 /* ProfileViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileViewController.swift; sourceTree = "<group>"; };
71 125BD57C22171D2A008A3575 /* ProfileViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileViewController.swift; sourceTree = "<group>"; };
64 125BD57E22171D73008A3575 /* Extentions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Extentions.swift; sourceTree = "<group>"; };
72 125BD57E22171D73008A3575 /* Extentions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Extentions.swift; sourceTree = "<group>"; };
65 125BD5802217314A008A3575 /* NewsVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewsVC.swift; sourceTree = "<group>"; };
73 125BD5802217314A008A3575 /* NewsVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewsVC.swift; sourceTree = "<group>"; };
74+ 1288B5CD221F1158002BE6B1 /* DataStorage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DataStorage.swift; sourceTree = "<group>"; };
75+ 1291BE2C2221312C009D3F23 /* ChannelsCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChannelsCoordinator.swift; sourceTree = "<group>"; };
76+ 1291BE332221569B009D3F23 /* TabbarCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabbarCoordinator.swift; sourceTree = "<group>"; };
77+ 12D7D132221C321600B35452 /* ChannelListController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChannelListController.swift; sourceTree = "<group>"; };
78+ 12D7D134221C42B700B35452 /* ChannelController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChannelController.swift; sourceTree = "<group>"; };
79+ 12D7D136221D78E800B35452 /* Channel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Channel.swift; sourceTree = "<group>"; };
66 12DB7FD622181CD20096878E /* BasicInfoController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BasicInfoController.swift; sourceTree = "<group>"; };
80 12DB7FD622181CD20096878E /* BasicInfoController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BasicInfoController.swift; sourceTree = "<group>"; };
67 12DB7FD822181E660096878E /* BasicInfoCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BasicInfoCell.swift; sourceTree = "<group>"; };
81 12DB7FD822181E660096878E /* BasicInfoCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BasicInfoCell.swift; sourceTree = "<group>"; };
68 12DB7FDA2218590C0096878E /* InfoCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InfoCell.swift; sourceTree = "<group>"; };
82 12DB7FDA2218590C0096878E /* InfoCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InfoCell.swift; sourceTree = "<group>"; };
@@ -81,8 +95,6 @@
81 12E36DB422143D54006FCDD7 /* TinyConstraints.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = TinyConstraints.framework; path = Carthage/Build/iOS/TinyConstraints.framework; sourceTree = "<group>"; };
95 12E36DB422143D54006FCDD7 /* TinyConstraints.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = TinyConstraints.framework; path = Carthage/Build/iOS/TinyConstraints.framework; sourceTree = "<group>"; };
82 12E36DB62214400A006FCDD7 /* Post.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Post.swift; sourceTree = "<group>"; };
96 12E36DB62214400A006FCDD7 /* Post.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Post.swift; sourceTree = "<group>"; };
83 12E36DB822144016006FCDD7 /* User.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = User.swift; sourceTree = "<group>"; };
97 12E36DB822144016006FCDD7 /* User.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = User.swift; sourceTree = "<group>"; };
84− 12E36DC522144266006FCDD7 /* HeaderNewsChannels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HeaderNewsChannels.swift; sourceTree = "<group>"; };
85− 12E36DC722144374006FCDD7 /* ChannelsController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChannelsController.swift; sourceTree = "<group>"; };
86 12E36DC922144635006FCDD7 /* NewPostViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewPostViewController.swift; sourceTree = "<group>"; };
98 12E36DC922144635006FCDD7 /* NewPostViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewPostViewController.swift; sourceTree = "<group>"; };
87 12E36DCB22144725006FCDD7 /* PostViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PostViewCell.swift; sourceTree = "<group>"; };
99 12E36DCB22144725006FCDD7 /* PostViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PostViewCell.swift; sourceTree = "<group>"; };
88 12E36DCD22144756006FCDD7 /* Constants.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Constants.swift; sourceTree = "<group>"; };
100 12E36DCD22144756006FCDD7 /* Constants.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Constants.swift; sourceTree = "<group>"; };
@@ -107,6 +119,27 @@
107/* End PBXFrameworksBuildPhase section */
119/* End PBXFrameworksBuildPhase section */
108
120
109/* Begin PBXGroup section */
121/* Begin PBXGroup section */
122+ 1288B5CC221F0EFE002BE6B1 /* Profile */ = {
123+ isa = PBXGroup;
124+ children = (
125+ 125BD57C22171D2A008A3575 /* ProfileViewController.swift */,
126+ 12DB7FDE221877160096878E /* InviteViewController.swift */,
127+ 12DB7FDC221872F80096878E /* SettingsViewController.swift */,
128+ 12DB7FD622181CD20096878E /* BasicInfoController.swift */,
129+ 12DB7FDA2218590C0096878E /* InfoCell.swift */,
130+ 12DB7FD822181E660096878E /* BasicInfoCell.swift */,
131+ );
132+ path = Profile;
133+ sourceTree = "<group>";
134+ };
135+ 1291BE32222154C3009D3F23 /* Coordinator tab bar? */ = {
136+ isa = PBXGroup;
137+ children = (
138+ 1291BE332221569B009D3F23 /* TabbarCoordinator.swift */,
139+ );
140+ path = "Coordinator tab bar?";
141+ sourceTree = "<group>";
142+ };
110 12E36D8F221424EA006FCDD7 = {
143 12E36D8F221424EA006FCDD7 = {
111 isa = PBXGroup;
144 isa = PBXGroup;
112 children = (
145 children = (
@@ -132,6 +165,8 @@
132 12E36D9A221424EA006FCDD7 /* GDproject */ = {
165 12E36D9A221424EA006FCDD7 /* GDproject */ = {
133 isa = PBXGroup;
166 isa = PBXGroup;
134 children = (
167 children = (
168+ 1288B5CD221F1158002BE6B1 /* DataStorage.swift */,
169+ 123E37A6221F1DD700F6E42A /* MainController.swift */,
135 12E36DCF22145923006FCDD7 /* Controller */,
170 12E36DCF22145923006FCDD7 /* Controller */,
136 12E36DCD22144756006FCDD7 /* Constants.swift */,
171 12E36DCD22144756006FCDD7 /* Constants.swift */,
137 125BD57E22171D73008A3575 /* Extentions.swift */,
172 125BD57E22171D73008A3575 /* Extentions.swift */,
@@ -148,6 +183,7 @@
148 isa = PBXGroup;
183 isa = PBXGroup;
149 children = (
184 children = (
150 12E36DB62214400A006FCDD7 /* Post.swift */,
185 12E36DB62214400A006FCDD7 /* Post.swift */,
186+ 12D7D136221D78E800B35452 /* Channel.swift */,
151 12E36DB822144016006FCDD7 /* User.swift */,
187 12E36DB822144016006FCDD7 /* User.swift */,
152 );
188 );
153 path = "Simple model";
189 path = "Simple model";
@@ -166,29 +202,27 @@
166 12E36DCF22145923006FCDD7 /* Controller */ = {
202 12E36DCF22145923006FCDD7 /* Controller */ = {
167 isa = PBXGroup;
203 isa = PBXGroup;
168 children = (
204 children = (
169− 125BD57C22171D2A008A3575 /* ProfileViewController.swift */,
205+ 1291BE32222154C3009D3F23 /* Coordinator tab bar? */,
170− 12DB7FDE221877160096878E /* InviteViewController.swift */,
206+ 123E37A4221F1B3200F6E42A /* LogInViewController.swift */,
171− 12DB7FDC221872F80096878E /* SettingsViewController.swift */,
207+ 1288B5CC221F0EFE002BE6B1 /* Profile */,
172− 12DB7FD622181CD20096878E /* BasicInfoController.swift */,
173− 12DB7FDA2218590C0096878E /* InfoCell.swift */,
174− 12DB7FD822181E660096878E /* BasicInfoCell.swift */,
175− 12E36DD322156519006FCDD7 /* News */,
208+ 12E36DD322156519006FCDD7 /* News and channels */,
176 );
209 );
177 path = Controller;
210 path = Controller;
178 sourceTree = "<group>";
211 sourceTree = "<group>";
179 };
212 };
180− 12E36DD322156519006FCDD7 /* News */ = {
213+ 12E36DD322156519006FCDD7 /* News and channels */ = {
181 isa = PBXGroup;
214 isa = PBXGroup;
182 children = (
215 children = (
216+ 12D7D134221C42B700B35452 /* ChannelController.swift */,
217+ 12D7D132221C321600B35452 /* ChannelListController.swift */,
183 12E36DC922144635006FCDD7 /* NewPostViewController.swift */,
218 12E36DC922144635006FCDD7 /* NewPostViewController.swift */,
184 12E36DD022148122006FCDD7 /* FullPostController.swift */,
219 12E36DD022148122006FCDD7 /* FullPostController.swift */,
185− 12E36DC522144266006FCDD7 /* HeaderNewsChannels.swift */,
186− 12E36DC722144374006FCDD7 /* ChannelsController.swift */,
187 12E36D9D221424EA006FCDD7 /* NewsController.swift */,
220 12E36D9D221424EA006FCDD7 /* NewsController.swift */,
221+ 1291BE2C2221312C009D3F23 /* ChannelsCoordinator.swift */,
188 125BD5802217314A008A3575 /* NewsVC.swift */,
222 125BD5802217314A008A3575 /* NewsVC.swift */,
189 12E36DCB22144725006FCDD7 /* PostViewCell.swift */,
223 12E36DCB22144725006FCDD7 /* PostViewCell.swift */,
190 );
224 );
191− path = News;
225+ path = " News and channels";
192 sourceTree = "<group>";
226 sourceTree = "<group>";
193 };
227 };
194 12E36DDA221594B1006FCDD7 /* Frameworks */ = {
228 12E36DDA221594B1006FCDD7 /* Frameworks */ = {
@@ -271,25 +305,30 @@
271 buildActionMask = 2147483647;
305 buildActionMask = 2147483647;
272 files = (
306 files = (
273 12E36DD522156559006FCDD7 /* MyStackView.swift in Sources */,
307 12E36DD522156559006FCDD7 /* MyStackView.swift in Sources */,
274− 12E36DC822144374006FCDD7 /* ChannelsController.swift in Sources */,
308+ 12D7D137221D78E800B35452 /* Channel.swift in Sources */,
275 12E36DB922144016006FCDD7 /* User.swift in Sources */,
309 12E36DB922144016006FCDD7 /* User.swift in Sources */,
276 125BD5812217314A008A3575 /* NewsVC.swift in Sources */,
310 125BD5812217314A008A3575 /* NewsVC.swift in Sources */,
277 12E36DB72214400A006FCDD7 /* Post.swift in Sources */,
311 12E36DB72214400A006FCDD7 /* Post.swift in Sources */,
278 12DB7FDF221877160096878E /* InviteViewController.swift in Sources */,
312 12DB7FDF221877160096878E /* InviteViewController.swift in Sources */,
279 12E36DCA22144635006FCDD7 /* NewPostViewController.swift in Sources */,
313 12E36DCA22144635006FCDD7 /* NewPostViewController.swift in Sources */,
280 12E36D9E221424EA006FCDD7 /* NewsController.swift in Sources */,
314 12E36D9E221424EA006FCDD7 /* NewsController.swift in Sources */,
281− 12E36DC622144266006FCDD7 /* HeaderNewsChannels.swift in Sources */,
282 12E36DCC22144725006FCDD7 /* PostViewCell.swift in Sources */,
315 12E36DCC22144725006FCDD7 /* PostViewCell.swift in Sources */,
316+ 123E37A5221F1B3200F6E42A /* LogInViewController.swift in Sources */,
283 125BD57F22171D73008A3575 /* Extentions.swift in Sources */,
317 125BD57F22171D73008A3575 /* Extentions.swift in Sources */,
318+ 12D7D133221C321600B35452 /* ChannelListController.swift in Sources */,
319+ 1291BE342221569B009D3F23 /* TabbarCoordinator.swift in Sources */,
320+ 1291BE2D2221312D009D3F23 /* ChannelsCoordinator.swift in Sources */,
284 12E36DD122148122006FCDD7 /* FullPostController.swift in Sources */,
321 12E36DD122148122006FCDD7 /* FullPostController.swift in Sources */,
322+ 1288B5CE221F1158002BE6B1 /* DataStorage.swift in Sources */,
285 125BD57D22171D2A008A3575 /* ProfileViewController.swift in Sources */,
323 125BD57D22171D2A008A3575 /* ProfileViewController.swift in Sources */,
286 12DB7FDB2218590C0096878E /* InfoCell.swift in Sources */,
324 12DB7FDB2218590C0096878E /* InfoCell.swift in Sources */,
287 12DB7FD922181E660096878E /* BasicInfoCell.swift in Sources */,
325 12DB7FD922181E660096878E /* BasicInfoCell.swift in Sources */,
326+ 12D7D135221C42B700B35452 /* ChannelController.swift in Sources */,
288 12E36D9C221424EA006FCDD7 /* AppDelegate.swift in Sources */,
327 12E36D9C221424EA006FCDD7 /* AppDelegate.swift in Sources */,
289 12DB7FD722181CD20096878E /* BasicInfoController.swift in Sources */,
328 12DB7FD722181CD20096878E /* BasicInfoController.swift in Sources */,
290 12E36DCE22144756006FCDD7 /* Constants.swift in Sources */,
329 12E36DCE22144756006FCDD7 /* Constants.swift in Sources */,
291 12DB7FDD221872F80096878E /* SettingsViewController.swift in Sources */,
330 12DB7FDD221872F80096878E /* SettingsViewController.swift in Sources */,
292−
331+ 123E37A7221F1DD700F6E42A /* MainController.swift in Sources */,
293 );
332 );
294 runOnlyForDeploymentPostprocessing = 0;
333 runOnlyForDeploymentPostprocessing = 0;
295 };
334 };
GDproject/Base.lproj/Main.storyboard+179−36
@@ -1,5 +1,5 @@
1<?xml version="1.0" encoding="UTF-8"?>
1<?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">
3 <device id="retina4_7" orientation="portrait">
3 <device id="retina4_7" orientation="portrait">
4 <adaptation id="fullscreen"/>
4 <adaptation id="fullscreen"/>
5 </device>
5 </device>
@@ -11,37 +11,6 @@
11 <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
11 <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
12 </dependencies>
12 </dependencies>
13 <scenes>
13 <scenes>
14− <!--News Controller-->
15− <scene sceneID="tne-QT-ifu">
16− <objects>
17− <viewController id="BYZ-38-t0r" customClass="NewsController" customModule="GDproject" customModuleProvider="target" sceneMemberID="viewController">
18− <view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
19− <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
20− <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
21− <subviews>
22− <tableView clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="default" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="28" sectionFooterHeight="28" translatesAutoresizingMaskIntoConstraints="NO" id="bdn-EE-6KU">
23− <rect key="frame" x="0.0" y="116" width="375" height="502"/>
24− <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
25− </tableView>
26− </subviews>
27− <color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
28− <constraints>
29− <constraint firstItem="bdn-EE-6KU" firstAttribute="leading" secondItem="6Tk-OE-BBY" secondAttribute="leading" id="Mwc-qc-ZfA"/>
30− <constraint firstItem="bdn-EE-6KU" firstAttribute="top" secondItem="6Tk-OE-BBY" secondAttribute="top" id="dww-F7-g9y"/>
31− <constraint firstItem="6Tk-OE-BBY" firstAttribute="trailing" secondItem="bdn-EE-6KU" secondAttribute="trailing" id="wlT-ZO-QGd"/>
32− <constraint firstItem="6Tk-OE-BBY" firstAttribute="bottom" secondItem="bdn-EE-6KU" secondAttribute="bottom" id="yXX-zW-vb8"/>
33− </constraints>
34− <viewLayoutGuide key="safeArea" id="6Tk-OE-BBY"/>
35− </view>
36− <navigationItem key="navigationItem" largeTitleDisplayMode="always" id="caN-kg-RZ4"/>
37− <connections>
38− <outlet property="tableView" destination="bdn-EE-6KU" id="O4Z-at-Hzw"/>
39− </connections>
40− </viewController>
41− <placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
42− </objects>
43− <point key="canvasLocation" x="2015.2" y="132.68365817091455"/>
44− </scene>
45 <!--Profile View Controller-->
14 <!--Profile View Controller-->
46 <scene sceneID="rQ6-TM-V7T">
15 <scene sceneID="rQ6-TM-V7T">
47 <objects>
16 <objects>
@@ -245,6 +214,104 @@
245 </objects>
214 </objects>
246 <point key="canvasLocation" x="2803" y="1756"/>
215 <point key="canvasLocation" x="2803" y="1756"/>
247 </scene>
216 </scene>
217+ <!--Channel List Controller-->
218+ <scene sceneID="4eb-Jz-gcx">
219+ <objects>
220+ <tableViewController storyboardIdentifier="ChannelListController" id="VzJ-FE-nbt" customClass="ChannelListController" customModule="GDproject" customModuleProvider="target" sceneMemberID="viewController">
221+ <tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="default" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="28" sectionFooterHeight="28" id="5RL-OH-B9N">
222+ <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
223+ <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
224+ <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
225+ <prototypes>
226+ <tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="none" indentationWidth="10" reuseIdentifier="ChannelCell" textLabel="MAo-lZ-MFd" detailTextLabel="KTs-9K-R13" style="IBUITableViewCellStyleSubtitle" id="65E-UC-AJO">
227+ <rect key="frame" x="0.0" y="28" width="375" height="44"/>
228+ <autoresizingMask key="autoresizingMask"/>
229+ <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="65E-UC-AJO" id="N5k-ip-WkW">
230+ <rect key="frame" x="0.0" y="0.0" width="375" height="43.5"/>
231+ <autoresizingMask key="autoresizingMask"/>
232+ <subviews>
233+ <label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="Title" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="MAo-lZ-MFd">
234+ <rect key="frame" x="16" y="5" width="33.5" height="20.5"/>
235+ <autoresizingMask key="autoresizingMask"/>
236+ <fontDescription key="fontDescription" type="system" pointSize="17"/>
237+ <nil key="textColor"/>
238+ <nil key="highlightedColor"/>
239+ </label>
240+ <label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="Subtitle" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="KTs-9K-R13">
241+ <rect key="frame" x="16" y="25.5" width="44" height="14.5"/>
242+ <autoresizingMask key="autoresizingMask"/>
243+ <fontDescription key="fontDescription" type="system" pointSize="12"/>
244+ <nil key="textColor"/>
245+ <nil key="highlightedColor"/>
246+ </label>
247+ </subviews>
248+ </tableViewCellContentView>
249+ </tableViewCell>
250+ </prototypes>
251+ <connections>
252+ <outlet property="dataSource" destination="VzJ-FE-nbt" id="XQW-UU-t6A"/>
253+ <outlet property="delegate" destination="VzJ-FE-nbt" id="xee-fv-SfO"/>
254+ </connections>
255+ </tableView>
256+ </tableViewController>
257+ <placeholder placeholderIdentifier="IBFirstResponder" id="9RU-Bp-4K5" userLabel="First Responder" sceneMemberID="firstResponder"/>
258+ </objects>
259+ <point key="canvasLocation" x="2708" y="-597"/>
260+ </scene>
261+ <!--Channel Controller-->
262+ <scene sceneID="ugM-Od-pJd">
263+ <objects>
264+ <viewController storyboardIdentifier="ChannelController" id="SgI-bH-MqV" customClass="ChannelController" customModule="GDproject" customModuleProvider="target" sceneMemberID="viewController">
265+ <view key="view" contentMode="scaleToFill" id="edj-KS-H90">
266+ <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
267+ <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
268+ <subviews>
269+ <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="5My-GH-WDq">
270+ <rect key="frame" x="0.0" y="20" width="375" height="54"/>
271+ <subviews>
272+ <textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" placeholder="Title" textAlignment="natural" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="VFE-We-ctc">
273+ <rect key="frame" x="16" y="12" width="343" height="30"/>
274+ <color key="backgroundColor" cocoaTouchSystemColor="groupTableViewBackgroundColor"/>
275+ <fontDescription key="fontDescription" type="system" pointSize="14"/>
276+ <textInputTraits key="textInputTraits"/>
277+ </textField>
278+ </subviews>
279+ <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
280+ <constraints>
281+ <constraint firstAttribute="height" constant="54" id="AX7-No-rwt"/>
282+ <constraint firstItem="VFE-We-ctc" firstAttribute="leading" secondItem="5My-GH-WDq" secondAttribute="leading" constant="16" id="HBN-OE-miW"/>
283+ <constraint firstItem="VFE-We-ctc" firstAttribute="top" secondItem="5My-GH-WDq" secondAttribute="top" constant="12" id="N8q-hz-5yP"/>
284+ <constraint firstAttribute="bottom" secondItem="VFE-We-ctc" secondAttribute="bottom" constant="12" id="jqO-53-maF"/>
285+ <constraint firstAttribute="trailing" secondItem="VFE-We-ctc" secondAttribute="trailing" constant="16" id="zYt-AY-R9F"/>
286+ </constraints>
287+ </view>
288+ <tableView clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="default" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="28" sectionFooterHeight="28" translatesAutoresizingMaskIntoConstraints="NO" id="fye-z6-WKO">
289+ <rect key="frame" x="0.0" y="74" width="375" height="593"/>
290+ <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
291+ </tableView>
292+ </subviews>
293+ <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
294+ <constraints>
295+ <constraint firstItem="fye-z6-WKO" firstAttribute="top" secondItem="5My-GH-WDq" secondAttribute="bottom" id="73C-jP-zKv"/>
296+ <constraint firstItem="C5s-a1-LTb" firstAttribute="bottom" secondItem="fye-z6-WKO" secondAttribute="bottom" id="HUf-vU-oDj"/>
297+ <constraint firstItem="fye-z6-WKO" firstAttribute="leading" secondItem="C5s-a1-LTb" secondAttribute="leading" id="Hbj-fv-SB5"/>
298+ <constraint firstItem="5My-GH-WDq" firstAttribute="top" secondItem="C5s-a1-LTb" secondAttribute="top" id="Ms5-z0-6i1"/>
299+ <constraint firstItem="5My-GH-WDq" firstAttribute="trailing" secondItem="C5s-a1-LTb" secondAttribute="trailing" id="Pt4-do-bce"/>
300+ <constraint firstItem="5My-GH-WDq" firstAttribute="leading" secondItem="C5s-a1-LTb" secondAttribute="leading" id="pgz-uB-BfM"/>
301+ <constraint firstItem="C5s-a1-LTb" firstAttribute="trailing" secondItem="fye-z6-WKO" secondAttribute="trailing" id="zHE-tP-Siv"/>
302+ </constraints>
303+ <viewLayoutGuide key="safeArea" id="C5s-a1-LTb"/>
304+ </view>
305+ <connections>
306+ <outlet property="tableView" destination="fye-z6-WKO" id="S11-YV-PU6"/>
307+ <outlet property="textField" destination="VFE-We-ctc" id="6pP-P4-zg8"/>
308+ <outlet property="viewww" destination="5My-GH-WDq" id="SS0-Mi-QWf"/>
309+ </connections>
310+ </viewController>
311+ <placeholder placeholderIdentifier="IBFirstResponder" id="fzv-8a-15V" userLabel="First Responder" sceneMemberID="firstResponder"/>
312+ </objects>
313+ <point key="canvasLocation" x="3560.8000000000002" y="-597.75112443778119"/>
314+ </scene>
248 <!--New Post View Controller-->
315 <!--New Post View Controller-->
249 <scene sceneID="TVK-xu-UdJ">
316 <scene sceneID="TVK-xu-UdJ">
250 <objects>
317 <objects>
@@ -294,10 +361,53 @@
294 </objects>
361 </objects>
295 <point key="canvasLocation" x="3444" y="129.98500749625188"/>
362 <point key="canvasLocation" x="3444" y="129.98500749625188"/>
296 </scene>
363 </scene>
364+ <!--Log In View Controller-->
365+ <scene sceneID="Pkd-pB-bQs">
366+ <objects>
367+ <viewController storyboardIdentifier="LogInController" id="ZCz-70-hDh" customClass="LogInViewController" customModule="GDproject" customModuleProvider="target" sceneMemberID="viewController">
368+ <view key="view" contentMode="scaleToFill" id="1q2-4g-KZs">
369+ <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
370+ <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
371+ <subviews>
372+ <stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="12" translatesAutoresizingMaskIntoConstraints="NO" id="UwC-m5-jA5">
373+ <rect key="frame" x="16" y="100" width="343" height="83"/>
374+ <subviews>
375+ <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Log In" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="efn-ze-jca">
376+ <rect key="frame" x="0.0" y="0.0" width="343" height="41"/>
377+ <fontDescription key="fontDescription" type="boldSystem" pointSize="34"/>
378+ <nil key="textColor"/>
379+ <nil key="highlightedColor"/>
380+ </label>
381+ <textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" placeholder="Mail" textAlignment="natural" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="mFP-WG-jY5">
382+ <rect key="frame" x="0.0" y="53" width="343" height="30"/>
383+ <color key="backgroundColor" cocoaTouchSystemColor="groupTableViewBackgroundColor"/>
384+ <nil key="textColor"/>
385+ <fontDescription key="fontDescription" type="system" pointSize="14"/>
386+ <textInputTraits key="textInputTraits"/>
387+ </textField>
388+ </subviews>
389+ </stackView>
390+ </subviews>
391+ <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
392+ <constraints>
393+ <constraint firstItem="UwC-m5-jA5" firstAttribute="leading" secondItem="LOR-Yw-0FU" secondAttribute="leading" constant="16" id="M6z-nU-H40"/>
394+ <constraint firstItem="LOR-Yw-0FU" firstAttribute="trailing" secondItem="UwC-m5-jA5" secondAttribute="trailing" constant="16" id="jST-rr-MMX"/>
395+ <constraint firstItem="UwC-m5-jA5" firstAttribute="top" secondItem="LOR-Yw-0FU" secondAttribute="top" constant="80" id="rvy-Ii-bwS"/>
396+ </constraints>
397+ <viewLayoutGuide key="safeArea" id="LOR-Yw-0FU"/>
398+ </view>
399+ <connections>
400+ <outlet property="mailTextField" destination="mFP-WG-jY5" id="7SN-qe-DDm"/>
401+ </connections>
402+ </viewController>
403+ <placeholder placeholderIdentifier="IBFirstResponder" id="6e8-oo-bbc" userLabel="First Responder" sceneMemberID="firstResponder"/>
404+ </objects>
405+ <point key="canvasLocation" x="-466" y="-821"/>
406+ </scene>
297 <!--Posts-->
407 <!--Posts-->
298 <scene sceneID="RSd-UJ-34B">
408 <scene sceneID="RSd-UJ-34B">
299 <objects>
409 <objects>
300− <navigationController automaticallyAdjustsScrollViewInsets="NO" id="NuV-ZG-ld2" sceneMemberID="viewController">
410+ <navigationController storyboardIdentifier="navChannels" automaticallyAdjustsScrollViewInsets="NO" id="NuV-ZG-ld2" sceneMemberID="viewController">
301 <tabBarItem key="tabBarItem" title="Posts" id="dH2-sL-YsR"/>
411 <tabBarItem key="tabBarItem" title="Posts" id="dH2-sL-YsR"/>
302 <toolbarItems/>
412 <toolbarItems/>
303 <navigationBar key="navigationBar" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" largeTitles="YES" id="6qB-3A-tuL">
413 <navigationBar key="navigationBar" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" largeTitles="YES" id="6qB-3A-tuL">
@@ -306,17 +416,37 @@
306 </navigationBar>
416 </navigationBar>
307 <nil name="viewControllers"/>
417 <nil name="viewControllers"/>
308 <connections>
418 <connections>
309− <segue destination="BYZ-38-t0r" kind="relationship" relationship="rootViewController" id="ehh-1b-ZGK"/>
419+ <segue destination="Nqc-TI-ueQ" kind="relationship" relationship="rootViewController" id="2BZ-i4-uIE"/>
310 </connections>
420 </connections>
311 </navigationController>
421 </navigationController>
312 <placeholder placeholderIdentifier="IBFirstResponder" id="POV-5T-jeQ" userLabel="First Responder" sceneMemberID="firstResponder"/>
422 <placeholder placeholderIdentifier="IBFirstResponder" id="POV-5T-jeQ" userLabel="First Responder" sceneMemberID="firstResponder"/>
313 </objects>
423 </objects>
314 <point key="canvasLocation" x="1088.8" y="132.68365817091455"/>
424 <point key="canvasLocation" x="1088.8" y="132.68365817091455"/>
315 </scene>
425 </scene>
426+ <!--News Controller-->
427+ <scene sceneID="eR7-97-LRL">
428+ <objects>
429+ <tableViewController storyboardIdentifier="NewsController" id="Nqc-TI-ueQ" customClass="NewsController" customModule="GDproject" customModuleProvider="target" sceneMemberID="viewController">
430+ <tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="default" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="28" sectionFooterHeight="28" id="hwA-SE-xpS">
431+ <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
432+ <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
433+ <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
434+ <color key="sectionIndexBackgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
435+ <connections>
436+ <outlet property="dataSource" destination="Nqc-TI-ueQ" id="bu5-tQ-7lb"/>
437+ <outlet property="delegate" destination="Nqc-TI-ueQ" id="kTM-Be-8qb"/>
438+ </connections>
439+ </tableView>
440+ <navigationItem key="navigationItem" id="b8E-6f-hLM"/>
441+ </tableViewController>
442+ <placeholder placeholderIdentifier="IBFirstResponder" id="c9d-Kh-itI" userLabel="First Responder" sceneMemberID="firstResponder"/>
443+ </objects>
444+ <point key="canvasLocation" x="1880" y="136"/>
445+ </scene>
316 <!--Profile-->
446 <!--Profile-->
317 <scene sceneID="dJj-Hp-Wa9">
447 <scene sceneID="dJj-Hp-Wa9">
318 <objects>
448 <objects>
319− <navigationController automaticallyAdjustsScrollViewInsets="NO" id="tae-5q-wvT" sceneMemberID="viewController">
449+ <navigationController storyboardIdentifier="navPosts" automaticallyAdjustsScrollViewInsets="NO" id="tae-5q-wvT" sceneMemberID="viewController">
320 <tabBarItem key="tabBarItem" title="Profile" id="lYy-LQ-AcR"/>
450 <tabBarItem key="tabBarItem" title="Profile" id="lYy-LQ-AcR"/>
321 <toolbarItems/>
451 <toolbarItems/>
322 <navigationBar key="navigationBar" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" largeTitles="YES" id="q3a-ph-c8V">
452 <navigationBar key="navigationBar" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" largeTitles="YES" id="q3a-ph-c8V">
@@ -332,10 +462,23 @@
332 </objects>
462 </objects>
333 <point key="canvasLocation" x="1089" y="958"/>
463 <point key="canvasLocation" x="1089" y="958"/>
334 </scene>
464 </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>
335 <!--Tab Bar Controller-->
478 <!--Tab Bar Controller-->
336 <scene sceneID="HCR-WO-p7g">
479 <scene sceneID="HCR-WO-p7g">
337 <objects>
480 <objects>
338− <tabBarController automaticallyAdjustsScrollViewInsets="NO" id="IeP-4W-8LT" sceneMemberID="viewController">
481+ <tabBarController storyboardIdentifier="TabBar" automaticallyAdjustsScrollViewInsets="NO" id="IeP-4W-8LT" sceneMemberID="viewController">
339 <toolbarItems/>
482 <toolbarItems/>
340 <tabBar key="tabBar" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" id="3pl-mU-U30">
483 <tabBar key="tabBar" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" id="3pl-mU-U30">
341 <rect key="frame" x="0.0" y="0.0" width="1000" height="1000"/>
484 <rect key="frame" x="0.0" y="0.0" width="1000" height="1000"/>
GDproject/Constants.swift+25−3
@@ -6,16 +6,38 @@
6// Copyright © 2019 drHSE. All rights reserved.
6// Copyright © 2019 drHSE. All rights reserved.
7//
7//
8
8
9−//constant for cell in posts NewsController.swift
9+/// constant for cell in posts NewsController.swift
10let postCellId = "PostCell"
10let postCellId = "PostCell"
11+
11−// constant for segmented controll in NewsController.swift and ChannelsController.swift
12+/// constant for segmented controll in NewsController.swift and ChannelsController.swift
12let headerNewsChannelsVC = "HeaderSegmentedControll"
13let headerNewsChannelsVC = "HeaderSegmentedControll"
14+
13−// for transitioning to full post view
15+/// for transitioning to full post view
14let fullPostControllerId = "FullPostController"
16let fullPostControllerId = "FullPostController"
15
17
18+/// constant for dequing basic cell
16let basicInfoCellId = "BasicInfoCell"
19let basicInfoCellId = "BasicInfoCell"
17
20
21+/// constant for dequing info cell
18let infoCellId = "InfoCell"
22let infoCellId = "InfoCell"
19
23
24+/// constant for switching to view controller for invitations
20let inviteVC = "InviteViewController"
25let inviteVC = "InviteViewController"
21
26
27+/// constant for dequing basic cell
28+let channelCellId = "ChannelCell"
29+
30+/// constant for switching to channel list view controller for choosing channel
31+let channelListControllerId = "ChannelListController"
32+
33+/// constant for dequing channel item cell
34+let itemCellId = "ItemCell"
35+
36+/// constant for switching to view controller to add or edit one channel
37+let channelControllerId = "ChannelController"
38+
39+/// constant for switching to news controller
40+let newsController = "NewsController"
41+
42+/// constant for switching to view controller for log in app
43+let logInController = "LogInController"
GDproject/Controller/ News and channels/ChannelController.swiftnew file+226
@@ -0,0 +1,226 @@
1+//
2+// ChannelController.swift
3+// GDproject
4+//
5+// Created by cstore on 19/02/2019.
6+// Copyright © 2019 drHSE. All rights reserved.
7+//
8+
9+import UIKit
10+
11+protocol DataDelegate {
12+ func passData(for row: Int, channel: Channel)
13+}
14+
15+class ChannelController: UIViewController, UITableViewDelegate, UITableViewDataSource, UITextFieldDelegate, UISearchBarDelegate
16+{
17+ @IBOutlet weak var tableView: UITableView!
18+
19+ var index: Int?
20+ var channel: Channel?
21+ var myProtocol: DataDelegate?
22+
23+ var dataSource: [String] = []
24+
25+ var fullPeople: [String] = ["Other Ann", "Other Ilya", "Other Kostya", "Pasha", "Valera"]
26+
27+ var fullTags: [String] = ["# happy", "# sad", "# meme", "# shershakov", "# pupsik"]
28+
29+ @IBOutlet weak var viewww: UIView!
30+
31+ @IBOutlet weak var textField: UITextField!
32+
33+ override func viewDidLoad() {
34+ super.viewDidLoad()
35+ tableView.delegate = self
36+ tableView.dataSource = self
37+ dataSource = channel!.people
38+ tableView.register(UITableViewCell.self, forCellReuseIdentifier: itemCellId)
39+ tableView.reloadData()
40+ textField.delegate = self
41+ searchBar.delegate = self
42+ searchBar.selectedScopeButtonIndex = 0
43+ navigationItem.title = channel?.title
44+ textField.placeholder = channel?.title
45+ textField.addTarget(self, action: #selector(changedText(_:)), for: .editingChanged)
46+ }
47+
48+ @objc func changedText(_ textField: UITextField){
49+ navigationItem.title = textField.text
50+ channel?.title = textField.text!
51+ myProtocol?.passData(for: index!, channel: channel!)
52+ }
53+
54+ func numberOfSections(in tableView: UITableView) -> Int {
55+ return 1
56+ }
57+
58+ func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
59+ return dataSource.count
60+ }
61+
62+ func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
63+ if searchBar.isFirstResponder {
64+ if let cell = tableView.cellForRow(at: indexPath)
65+ {
66+
67+ if cell.accessoryType == .none{
68+ switch searchBar.selectedScopeButtonIndex{
69+ case 0:
70+ channel?.people.append(dataSource[indexPath.row])
71+ print("people = \(channel!.people)")
72+ case 1:
73+ channel?.hashtags.append(dataSource[indexPath.row])
74+ print("hashtags = \(channel!.hashtags)")
75+ default:
76+ break
77+ }
78+
79+ cell.accessoryType = .checkmark
80+ } else {
81+ cell.accessoryType = .none
82+
83+ switch searchBar.selectedScopeButtonIndex{
84+ case 0:
85+ channel?.people = channel!.people.filter({ (s) -> Bool in
86+ !fullPeople[indexPath.row].contains(s)
87+ })
88+ // TODO: dataPass
89+ case 1:
90+ channel?.hashtags = channel!.hashtags.filter({ (s) -> Bool in
91+ !fullTags[indexPath.row].contains(s)
92+ })
93+ // TODO: dataPass
94+ default:
95+ break
96+ }
97+ }
98+ }
99+ } else
100+ {
101+ tableView.beginUpdates()
102+ dataSource.remove(at: indexPath.row)
103+ switch searchBar.selectedScopeButtonIndex{
104+ case 0:
105+ channel?.people.remove(at: indexPath.row)
106+ // TODO: dataPass
107+ case 1:
108+ channel?.hashtags.remove(at: indexPath.row)
109+ // TODO: dataPass
110+ default:
111+ break
112+ }
113+ tableView.deleteRows(at: [indexPath], with: .none)
114+ tableView.endUpdates()
115+ }
116+ }
117+
118+ func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
119+ let cell = tableView.dequeueReusableCell(withIdentifier: itemCellId, for: indexPath)
120+
121+ cell.textLabel?.text = dataSource[indexPath.row]
122+ cell.selectionStyle = .none
123+
124+ if channel!.hashtags.contains(dataSource[indexPath.row]) || channel!.people.contains(dataSource[indexPath.row])
125+ {
126+ cell.accessoryType = .checkmark
127+ } else {
128+ cell.accessoryType = .none
129+ }
130+
131+ return cell
132+ }
133+
134+ func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
135+ return 100
136+ }
137+
138+ let searchBar: UISearchBar = {
139+ let searchBar = UISearchBar(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: 70))
140+ searchBar.showsScopeBar = true
141+ searchBar.showsCancelButton = true
142+ searchBar.scopeButtonTitles = ["People", "Tags"]
143+ return searchBar
144+ }()
145+
146+ func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView?
147+ {
148+ let view = UIView(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: 70))
149+
150+ if flag {
151+ searchBar.selectedScopeButtonIndex = 1
152+ } else {
153+ searchBar.selectedScopeButtonIndex = 0
154+ }
155+
156+ view.addSubview(searchBar)
157+ return view
158+ }
159+
160+ func textFieldShouldReturn(_ textField: UITextField) -> Bool
161+ {
162+ textField.resignFirstResponder()
163+ return true
164+ }
165+
166+ func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
167+ if searchText.isEmpty {
168+ dataSource = searchBar.selectedScopeButtonIndex == 0 ? fullPeople : fullTags
169+ tableView.reloadData()
170+ } else {
171+ filterTableView(ind: searchBar.selectedScopeButtonIndex, text: searchText)
172+ }
173+ }
174+
175+ func filterTableView(ind: Int, text: String){
176+ switch ind {
177+ case 0:
178+ dataSource = fullPeople.filter({ (s) -> Bool in
179+ s.lowercased().contains(text.lowercased())
180+ })
181+ tableView.reloadData()
182+ case 1:
183+ dataSource = fullTags.filter({ (s) -> Bool in
184+ s.lowercased().contains(text.lowercased())
185+ })
186+ tableView.reloadData()
187+ default:
188+ break
189+ }
190+ }
191+
192+ var flag = false
193+
194+ func searchBar(_ searchBar: UISearchBar, selectedScopeButtonIndexDidChange selectedScope: Int) {
195+ if searchBar.isFirstResponder {
196+ dataSource = searchBar.selectedScopeButtonIndex == 0 ? fullPeople : fullTags
197+ flag = searchBar.selectedScopeButtonIndex == 0 ? false : true
198+ if (!(searchBar.text?.isEmpty ?? true))
199+ {
200+ filterTableView(ind: selectedScope, text: searchBar.text!)
201+ }
202+ tableView.reloadData()
203+ } else if !(searchBar.isFirstResponder){
204+ dataSource = searchBar.selectedScopeButtonIndex == 0 ? channel!.people : channel!.hashtags
205+ flag = searchBar.selectedScopeButtonIndex == 0 ? false : true
206+ tableView.reloadData()
207+ }
208+ }
209+
210+ func searchBarTextDidEndEditing(_ searchBar: UISearchBar) {
211+ dataSource = searchBar.selectedScopeButtonIndex == 0 ? channel!.people : channel!.hashtags
212+ flag = searchBar.selectedScopeButtonIndex == 0 ? false : true
213+ tableView.reloadData()
214+ }
215+
216+ func searchBarTextDidBeginEditing(_ searchBar: UISearchBar) {
217+ dataSource = searchBar.selectedScopeButtonIndex == 0 ? fullPeople : fullTags
218+ flag = searchBar.selectedScopeButtonIndex == 0 ? false : true
219+ tableView.reloadData()
220+ }
221+
222+ func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
223+ searchBar.text = ""
224+ searchBar.resignFirstResponder()
225+ }
226+}
GDproject/Controller/ News and channels/ChannelListController.swiftnew file+185
@@ -0,0 +1,185 @@
1+//
2+// ChannelListController.swift
3+// GDproject
4+//
5+// Created by cstore on 19/02/2019.
6+// Copyright © 2019 drHSE. All rights reserved.
7+//
8+
9+import UIKit
10+
11+struct ChannelData{
12+ var title = String()
13+ var subtitle = String()
14+}
15+
16+// TODO: make search controller availiable
17+class ChannelListController: UITableViewController, DataDelegate {
18+
19+ // MARK: - Output -
20+ var onChannelSelected: ((Channel) -> Void)?
21+
22+ // MARK:- filter search controller
23+ var filteredDataSource = [Channel]()
24+
25+ var myProtocol: DataDelegate?
26+ var displayingChannel: Channel?
27+
28+ var isFiltering: Bool {
29+ return searchController.isActive && !searchBarIsEmpty()
30+ }
31+
32+ func searchBarIsEmpty() -> Bool {
33+ return searchController.searchBar.text?.isEmpty ?? true
34+ }
35+
36+ func filterContentForSearchText(_ searchText: String, scope: String = "All")
37+ {
38+ filteredDataSource = ChannelListController.dataSource.filter({(keys : Channel) -> Bool in
39+ return keys.title.lowercased().contains(searchText.lowercased())
40+ })
41+
42+ tableView.reloadData()
43+ }
44+
45+ func passData(for row: Int, channel: Channel) {
46+ ChannelListController.dataSource[row] = channel
47+ }
48+
49+ var searchController = UISearchController(searchResultsController: nil)
50+
51+ override func viewDidLoad() {
52+ super.viewDidLoad()
53+ setUpNavigationBar()
54+ navigationItem.title = "Channels"
55+ searchController.searchResultsUpdater = self
56+ searchController.obscuresBackgroundDuringPresentation = false
57+ searchController.searchBar.placeholder = "Search channel"
58+ navigationItem.searchController = searchController
59+ definesPresentationContext = true
60+ }
61+
62+ func setUpNavigationBar(){
63+ navigationController?.navigationItem.largeTitleDisplayMode = .always
64+ navigationItem.rightBarButtonItems = [UIBarButtonItem(barButtonSystemItem: .add, target: self, action: #selector(addChannel))]
65+ }
66+
67+ override func viewWillAppear(_ animated: Bool)
68+ {
69+ super.viewWillAppear(animated)
70+ searchController.isActive = false
71+ tableView.reloadData()
72+ }
73+
74+ @objc func addChannel()
75+ {
76+ // insertion
77+ tableView.beginUpdates()
78+ ChannelListController.dataSource.insert(Channel(title: "Untitled", subtitle: "No", hashtags: [], people: [], posts: []), at: 1)
79+ tableView.insertRows(at: [IndexPath(row: 1, section: 0)], with: .none)
80+ tableView.endUpdates()
81+
82+ // editing mode is on automatically
83+ let vc = storyboard?.instantiateViewController(withIdentifier: channelControllerId) as! ChannelController
84+ vc.index = 1
85+ vc.myProtocol = self
86+ vc.channel = ChannelListController.dataSource[1]
87+ navigationController?.pushViewController(vc, animated: true)
88+ }
89+
90+ static var dataSource : [Channel] = [
91+ Channel(title: "General", subtitle: "All posts", hashtags: ["All"], people: ["All"], posts: []),
92+ 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")]),
93+ Channel(title: "Title2", subtitle: "subtitle2", hashtags: ["# studyhard", "# university"], people: ["Pasha", "Olya", "Andrey", "Ilya"], posts:
94+ [
95+ 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"),
96+ 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")
97+ ]),
98+ 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")])
99+ ]
100+
101+ override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
102+ if isFiltering {
103+ return filteredDataSource.count
104+ } else {
105+ return ChannelListController.dataSource.count
106+ }
107+ }
108+
109+ override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
110+ {
111+
112+ let cell = tableView.dequeueReusableCell(withIdentifier: channelCellId, for: indexPath)
113+
114+
115+ if isFiltering{
116+ cell.textLabel?.text = filteredDataSource[indexPath.row].title
117+ cell.detailTextLabel?.text = filteredDataSource[indexPath.row].subtitle
118+ } else {
119+ cell.textLabel?.text = ChannelListController.dataSource[indexPath.row].title
120+ cell.detailTextLabel?.text = ChannelListController.dataSource[indexPath.row].subtitle
121+ }
122+
123+ return cell
124+ }
125+
126+
127+ override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
128+ switch indexPath.row {
129+ case 0:
130+ return false
131+ default:
132+ return true
133+ }
134+ }
135+
136+ override func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]?
137+ {
138+
139+ let editButton = UITableViewRowAction(style: .normal, title: "Edit") { [weak self] (action, indexPath) in
140+ let vc = self?.storyboard?.instantiateViewController(withIdentifier: channelControllerId) as! ChannelController
141+ vc.index = indexPath.row
142+ vc.myProtocol = self!
143+ vc.channel = ChannelListController.dataSource[indexPath.row]
144+ self?.navigationController?.pushViewController(vc, animated: true)
145+ }
146+ editButton.backgroundColor = .green
147+
148+
149+ let deleteButton = UITableViewRowAction(style: .normal, title: "Delete") { [weak self] (action, indexPath) in
150+ if (ChannelListController.dataSource[indexPath.row] == self!.displayingChannel!)
151+ {
152+ self?.myProtocol?.passData(for: 0, channel: ChannelListController.dataSource[0])
153+ }
154+ self?.tableView.beginUpdates()
155+ ChannelListController.dataSource.remove(at: indexPath.row)
156+ self?.tableView.deleteRows(at: [indexPath], with: .none)
157+ self?.tableView.endUpdates()
158+ }
159+ deleteButton.backgroundColor = .red
160+
161+
162+ return [editButton, deleteButton]
163+ }
164+
165+ // TODO: remove popping
166+ override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
167+ {
168+ if isFiltering {
169+ //onChannelSelected?(filteredDataSource[indexPath.row])
170+ myProtocol?.passData(for: 0, channel: filteredDataSource[indexPath.row])
171+ navigationController?.popViewController(animated: true)
172+ } else {
173+ myProtocol?.passData(for: 0, channel: ChannelListController.dataSource[indexPath.row])
174+ navigationController?.popViewController(animated: true)
175+ //onChannelSelected?(ChannelListController.dataSource[indexPath.row])
176+ }
177+ }
178+}
179+
180+
181+extension ChannelListController : UISearchResultsUpdating {
182+ func updateSearchResults(for searchController: UISearchController) {
183+ filterContentForSearchText(searchController.searchBar.text!)
184+ }
185+}
GDproject/Controller/ News and channels/ChannelsCoordinator.swiftnew file+55
@@ -0,0 +1,55 @@
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?.setViewControllers([controller], animated: false)
46+ //navigationController?.pushViewController(controller, animated: false)
47+ }
48+
49+ // MARK:- update only viewControllers which are depandable on chosen channel
50+ private func updateInterfaces() {
51+ navigationController?.viewControllers.forEach {
52+ ($0 as? UpdateableWithChannel)?.channel = channel
53+ }
54+ }
55+}
GDproject/Controller/News/FullPostController.swift → GDproject/Controller/ News and channels/FullPostController.swiftrenamed

The content is the same.

GDproject/Controller/News/NewPostViewController.swift → GDproject/Controller/ News and channels/NewPostViewController.swiftrenamed+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 → GDproject/Controller/ News and channels/NewsController.swiftrenamed+64−36
@@ -8,66 +8,97 @@
8
8
9import UIKit
9import UIKit
10import TinyConstraints
10import TinyConstraints
11+import Cartography
12+
13+protocol UpdateableWithChannel: class {
14+ var channel: Channel? { get set }
15+}
16+protocol NewPostDelegate {
17+ func addPost(post: Post)
18+}
11
19
12// MARK:- Controller with posts and channels availiable.
20// MARK:- Controller with posts and channels availiable.
13// Search is availiable within every table (posts and channels). Has button-functionality for boths post and chnnels
21// Search is availiable within every table (posts and channels). Has button-functionality for boths post and chnnels
14−class NewsController: UIViewController
22+class NewsController: UITableViewController, UISearchControllerDelegate, NewPostDelegate, UpdateableWithChannel, DataDelegate
15{
23{
16−
24+ func passData(for row: Int, channel: Channel) {
17− @IBOutlet weak var tableView: UITableView!
25+ self.channel = channel
26+ }
18
27
19− var searchController = UISearchController(searchResultsController: nil)
28+ var channel: Channel?{
29+ didSet{
30+ news.dataSourse = channel?.posts ?? []
31+ navigationItem.title = channel?.title ?? ""
32+ }
33+ }
20
34
21− var dataSourse: [Post] = [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 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é. Il a été popularisé dans les années 1960 grâce à la vente de feuilles Letraset contenant des passages du Lorem Ipsum, et, plus récemment, par son inclusion dans des applications de mise en page de texte, comme Aldus PageMaker. \n On sait depuis longtemps que travailler avec du texte lisible et contenant du sens est source de distractions, et empêche de se concentrer sur la mise en page elle-même. 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, et en tout cas comparable avec celle du français standard. De nombreuses suites logicielles de mise en page ou éditeurs de sites Web ont fait du Lorem Ipsum leur faux texte par défaut, et une recherche pour 'Lorem Ipsum' vous conduira vers de nombreux sites qui n'en sont encore qu'à leur phase de construction. Plusieurs versions sont apparues avec le temps, parfois 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")]
35+ // MARK: - Output -
36+ var onSelectChannel: (() -> Void)?
37+
38+ func addPost(post: Post) {
39+ news.dataSourse.insert(post, at: 0)
40+ }
22
41
42+ var searchController = UISearchController(searchResultsController: nil)
43+
23 var news = NewsVC()
44 var news = NewsVC()
24− var channels = ChannelsController()
25
45
26 override func viewDidLoad()
46 override func viewDidLoad()
27 {
47 {
28 super.viewDidLoad()
48 super.viewDidLoad()
29− tableView.register(HeaderNewsChannels.self, forCellReuseIdentifier: headerNewsChannelsVC)
49+ channel = ChannelListController.dataSource[0]
30− tableView.register(PostViewCell.self, forCellReuseIdentifier: postCellId)
31−
32− news.dataSourse = dataSourse
33− news.viewController = self
34
50
35− news.type = .NEWS("Posts", "Channels")
51+ tableView.register(PostViewCell.self, forCellReuseIdentifier: postCellId)
52+ tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell")
36
53
37− tableView.delegate = news
54+ searchController.delegate = self
38− tableView.dataSource = news
55+ searchController.obscuresBackgroundDuringPresentation = false
39− tableView.reloadData()
56+ navigationItem.searchController = searchController
57+ definesPresentationContext = true
58+ searchController.searchBar.placeholder = "Search anything"
40
59
60+ news.dataSourse = channel!.posts
61+ news.viewController = self
41
62
63+ news.type = .NONE
42
64
43 setUpNavigationItemsforPosts()
65 setUpNavigationItemsforPosts()
44− searchController.searchBar.placeholder = "Search anything"
66+
45−
46− navigationItem.searchController = searchController
47− definesPresentationContext = true
48−
49− setUpBanner()
67+ //setUpBanner()
50 }
68 }
51
69
70+
71+ let label : UILabel = {
72+ let label = UILabel()
73+ label.text = "No posts to display yet!"
74+ label.font = UIFont.systemFont(ofSize: 18)
75+ label.textColor = .black
76+ label.isHidden = true
77+ label.numberOfLines = 0
78+ return label
79+ }()
80+
52 override func viewWillAppear(_ animated: Bool) {
81 override func viewWillAppear(_ animated: Bool) {
53 super.viewWillAppear(animated)
82 super.viewWillAppear(animated)
54− navigationController?.navigationBar.prefersLargeTitles = true
83+ searchController.isActive = false
84+ // TODO:- display something if no posts are availiable
85+ tableView.reloadData()
55 }
86 }
56
87
57 func setUpNavigationItemsforPosts(){
88 func setUpNavigationItemsforPosts(){
58− navigationItem.title = "Posts"
59− navigationItem.rightBarButtonItems = [UIBarButtonItem(barButtonSystemItem: .compose, target: self, action: #selector(self.writePost(_:)))]
89+ navigationItem.rightBarButtonItems = [UIBarButtonItem(barButtonSystemItem: .compose, target: self, action: #selector(self.writePost(_:))),UIBarButtonItem(barButtonSystemItem: .search, target: self, action: #selector(self.showChannels(_:)))
90+ ]
60 tableView.delegate = news
91 tableView.delegate = news
61 tableView.dataSource = news
92 tableView.dataSource = news
62 tableView.reloadData()
93 tableView.reloadData()
63 }
94 }
64
95
65− func setUpNavigationItemsForChannels(){
96+ // MARK:- attempt with coordinator
66− navigationItem.title = "Channels"
97+ @objc func showChannels(_ barItem: UIBarButtonItem){
67− navigationItem.rightBarButtonItems = [UIBarButtonItem(barButtonSystemItem: .add, target: self, action: #selector(addChannel))]
98+ let vc = UIStoryboard.makeChannelsListController()
68− tableView.delegate = channels
99+ vc.myProtocol = self
69− tableView.dataSource = channels
100+ vc.displayingChannel = channel
70− tableView.reloadData()
101+ self.navigationController?.pushViewController(vc, animated: true)
71 }
102 }
72
103
73 @objc func writePost(_ barItem: UIBarButtonItem)
104 @objc func writePost(_ barItem: UIBarButtonItem)
@@ -77,7 +108,7 @@ class NewsController: UIViewController
77 vc.navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Post", style: .plain, target: vc, action: #selector(vc.newPost))
108 vc.navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Post", style: .plain, target: vc, action: #selector(vc.newPost))
78 vc.navigationItem.leftBarButtonItem = UIBarButtonItem(title: "Close", style: .plain, target: vc, action: #selector(vc.closeView))
109 vc.navigationItem.leftBarButtonItem = UIBarButtonItem(title: "Close", style: .plain, target: vc, action: #selector(vc.closeView))
79
110
80− vc.parentVC = self
111+ vc.myProtocol = self
81
112
82 let transition = CATransition()
113 let transition = CATransition()
83 transition.duration = 0.5
114 transition.duration = 0.5
@@ -88,10 +119,6 @@ class NewsController: UIViewController
88 navigationController?.pushViewController(vc, animated: false)
119 navigationController?.pushViewController(vc, animated: false)
89 }
120 }
90
121
91− @objc func addChannel(){
92− print("Add channel")
93− }
94−
95 // for animating the banner
122 // for animating the banner
96 var topConstraint: NSLayoutConstraint?
123 var topConstraint: NSLayoutConstraint?
97
124
@@ -111,6 +138,7 @@ class NewsController: UIViewController
111 return label
138 return label
112 }()
139 }()
113
140
141+ // MARK:- banner
114 private func setUpBanner()
142 private func setUpBanner()
115 {
143 {
116 view.addSubview(bannerView)
144 view.addSubview(bannerView)
@@ -149,7 +177,7 @@ class NewsController: UIViewController
149
177
150 var isBannerVisible: Bool = false
178 var isBannerVisible: Bool = false
151
179
152− func scrollViewDidScroll(_ scrollView: UIScrollView) {
180+ override func scrollViewDidScroll(_ scrollView: UIScrollView) {
153 print(scrollView.contentOffset.y)
181 print(scrollView.contentOffset.y)
154 if scrollView.contentOffset.y >= 50 && !isBannerVisible{
182 if scrollView.contentOffset.y >= 50 && !isBannerVisible{
155 isBannerVisible = true
183 isBannerVisible = true
GDproject/Controller/News/NewsVC.swift → GDproject/Controller/ News and channels/NewsVC.swiftrenamed+5−33
@@ -16,10 +16,13 @@ class NewsVC: UIViewController, UITableViewDelegate, UITableViewDataSource{
16
16
17 var viewController: UIViewController?
17 var viewController: UIViewController?
18
18
19+ func numberOfSections(in tableView: UITableView) -> Int {
20+ return 1
21+ }
22+
19 func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
23 func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
20 {
24 {
21 tableView.deselectRow(at: indexPath, animated: true)
25 tableView.deselectRow(at: indexPath, animated: true)
22−
23 let vc = viewController!.storyboard!.instantiateViewController(withIdentifier: fullPostControllerId) as! FullPostController
26 let vc = viewController!.storyboard!.instantiateViewController(withIdentifier: fullPostControllerId) as! FullPostController
24
27
25 vc.post = dataSourse[indexPath.row]
28 vc.post = dataSourse[indexPath.row]
@@ -46,41 +49,10 @@ class NewsVC: UIViewController, UITableViewDelegate, UITableViewDataSource{
46 func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
49 func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
47 return 100.0
50 return 100.0
48 }
51 }
49−
50− func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
51− switch type {
52− case .NONE:
53− return 0
54− default:
55− return 46
56− }
57− }
58−
59− func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView?
60− {
61− let cell = tableView.dequeueReusableCell(withIdentifier: headerNewsChannelsVC) as! HeaderNewsChannels
62−
63− cell.vc = viewController as? NewsController
64− cell.vcProfile = viewController as? ProfileViewController
65−
66− let view = UIView(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: 46.0))
67− view.addSubview(cell)
68− cell.edgesToSuperview()
69−
70− switch type {
71− case .NONE:
72− return nil
73− default:
74− return view
75− }
76− }
77−
78}
52}
79
53
80
54
81enum HeaderType {
55enum HeaderType {
82 case NONE
56 case NONE
83− case NEWS(String, String)
57+ case NEWS
84− case PROFILE(String, String)
85− case BASIC_INFO(String, String)
86}
58}
GDproject/Controller/News/PostViewCell.swift → GDproject/Controller/ News and channels/PostViewCell.swiftrenamed

The content is the same.

GDproject/Controller/Coordinator tab bar?/TabbarCoordinator.swiftnew file+13
@@ -0,0 +1,13 @@
1+import UIKit
2+
3+class TabbarCoordinator{
4+ var window: UIWindow!
5+
6+ func start(){
7+ window.rootViewController = UIStoryboard.tabBarController()
8+ }
9+
10+ init(window: UIWindow) {
11+ self.window = window
12+ }
13+}
GDproject/Controller/LogInViewController.swiftnew file+138
@@ -0,0 +1,138 @@
1+//
2+// LogInViewController.swift
3+// NewsFeed
4+//
5+// Created by cstore on 20/01/2019.
6+// Copyright © 2019 drHSE. All rights reserved.
7+//
8+
9+import UIKit
10+
11+class LogInViewController: UIViewController {
12+
13+ @IBOutlet weak var mailTextField: UITextField!
14+
15+ static let titleColor = UIColor(red: 0, green: 137/255, blue: 249/255, alpha: 0.5)
16+
17+ var bottomConstraint: NSLayoutConstraint?
18+
19+ let logInButton: UIButton = {
20+ let button = UIButton(type: .system)
21+ button.setTitle("Log In", for: .normal)
22+ button.setTitleColor(titleColor, for: .normal)
23+ button.titleLabel?.font = UIFont.boldSystemFont(ofSize: 16)
24+ button.isEnabled = false
25+ button.addTarget(self, action: #selector(activateLogInProcess), for: .touchUpInside)
26+ return button
27+ }()
28+
29+ let keyboardBar: UIView = {
30+ let view = UIView()
31+ view.backgroundColor = .white
32+ return view
33+ }()
34+
35+ override func viewDidLoad() {
36+ super.viewDidLoad()
37+ setUpView()
38+ configureTapgesture()
39+ }
40+
41+ override func viewWillAppear(_ animated: Bool) {
42+ super.viewWillAppear(animated)
43+ // MARK:- uncomment when mail registration will be availiable
44+ //self.navigationController?.setNavigationBarHidden(true, animated: animated)
45+ }
46+
47+ override func viewWillDisappear(_ animated: Bool) {
48+ super.viewWillDisappear(animated)
49+ // MARK:- uncomment when mail registration will be availiable
50+ //self.navigationController?.setNavigationBarHidden(false, animated: animated)
51+ }
52+
53+ private func configureTapgesture(){
54+ let tapGesture = UITapGestureRecognizer(target: self, action: #selector(handleTap))
55+ view.addGestureRecognizer(tapGesture)
56+ }
57+
58+ @objc func handleTap(){
59+ view.endEditing(true)
60+ }
61+
62+ @objc func activateLogInProcess(){
63+ if logInButton.isEnabled {
64+ // MARK:- when log in is succeeded do I need to go there?
65+ let vc = storyboard!.instantiateViewController(withIdentifier: newsController) as! NewsController
66+ present(vc, animated: true) {
67+ print("logged in")
68+ }
69+ DataStorage.standard.setIsLoggedIn(value: true)
70+ view.endEditing(true)
71+ }
72+ }
73+
74+ func setUpView(){
75+ mailTextField.delegate = self
76+ view.addSubview(keyboardBar)
77+
78+ view.addConstraintsWithFormat(format: "H:|[v0]|", views: keyboardBar)
79+ view.addConstraintsWithFormat(format: "V:[v0(50)]", views: keyboardBar)
80+
81+ setUpBarComponents()
82+
83+ bottomConstraint = NSLayoutConstraint(item: keyboardBar, attribute: .bottom, relatedBy: .equal, toItem: view.safeAreaLayoutGuide, attribute: .bottom, multiplier: 1, constant: 0)
84+ view.addConstraint(bottomConstraint!)
85+
86+ // for keyboard notifications
87+ NotificationCenter.default.addObserver(self, selector: #selector(handleKeyboardNotifications), name: UIResponder.keyboardWillShowNotification, object: nil)
88+
89+ NotificationCenter.default.addObserver(self, selector: #selector(handleKeyboardNotifications), name: UIResponder.keyboardWillHideNotification, object: nil)
90+
91+ // for log in button notifications
92+ NotificationCenter.default.addObserver(self, selector: #selector(inputDidChanged), name: UITextField.textDidChangeNotification, object: mailTextField)
93+
94+ NotificationCenter.default.addObserver(self, selector: #selector(inputDidChanged), name: UITextField.textDidBeginEditingNotification, object: mailTextField)
95+ }
96+
97+ @objc func inputDidChanged(notification: NSNotification){
98+ if mailTextField.text?.isEmpty ?? true
99+ {
100+ logInButton.isEnabled = false
101+ logInButton.setTitleColor(LogInViewController.titleColor.withAlphaComponent(0.5), for: .normal)
102+ }
103+ else
104+ {
105+ logInButton.isEnabled = true
106+ logInButton.setTitleColor(LogInViewController.titleColor.withAlphaComponent(1), for: .normal)
107+ }
108+ }
109+
110+ @objc func handleKeyboardNotifications(notification: NSNotification){
111+ if let userInfo = notification.userInfo{
112+ // UIKeyboardFrameEndUserInfoKey
113+ let keyBoardFrame = (userInfo[UIResponder.keyboardFrameEndUserInfoKey] as! NSValue).cgRectValue
114+ bottomConstraint?.constant = notification.name == UIResponder.keyboardWillShowNotification ? -keyBoardFrame.height+view.safeAreaInsets.bottom : 0
115+
116+ UIView.animate(withDuration: 0, delay: 0, options: .curveEaseOut, animations: {
117+ self.view.layoutIfNeeded()
118+ }) { (completed) in
119+
120+ }
121+ }
122+ }
123+
124+ func setUpBarComponents(){
125+ keyboardBar.addSubview(logInButton)
126+ keyboardBar.addConstraintsWithFormat(format: "H:[v0(60)]-16-|", views: logInButton)
127+ keyboardBar.addConstraintsWithFormat(format: "V:|[v0]|", views: logInButton)
128+ }
129+}
130+
131+
132+extension LogInViewController: UITextFieldDelegate{
133+ func textFieldShouldReturn(_ textField: UITextField) -> Bool
134+ {
135+ textField.resignFirstResponder()
136+ return true
137+ }
138+}
GDproject/Controller/News/ChannelsController.swiftdeleted−35
@@ -1,35 +0,0 @@
1−//
2−// PostTable.swift
3−// GDproject
4−//
5−// Created by cstore on 13/02/2019.
6−// Copyright © 2019 drHSE. All rights reserved.
7−//
8−
9−import UIKit
10−
11−class ChannelsController: UITableViewController {
12−
13− override func viewDidLoad() {
14− super.viewDidLoad()
15−
16− // Uncomment the following line to preserve selection between presentations
17− // self.clearsSelectionOnViewWillAppear = false
18−
19− // Uncomment the following line to display an Edit button in the navigation bar for this view controller.
20− // self.navigationItem.rightBarButtonItem = self.editButtonItem
21− }
22−
23− // MARK: - Table view data source
24−
25− override func numberOfSections(in tableView: UITableView) -> Int {
26− // #warning Incomplete implementation, return the number of sections
27− return 0
28− }
29−
30− override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
31− // #warning Incomplete implementation, return the number of rows
32− return 0
33− }
34−
35−}
GDproject/Controller/News/HeaderNewsChannels.swiftdeleted−54
@@ -1,54 +0,0 @@
1−//
2−// HeaderNewsChannels.swift
3−// GDproject
4−//
5−// Created by cstore on 13/02/2019.
6−// Copyright © 2019 drHSE. All rights reserved.
7−//
8−
9−import UIKit
10−import TinyConstraints
11−
12−class HeaderNewsChannels: UITableViewCell {
13−
14− weak var tableView: UITableView?
15−
16− weak var vc: NewsController?
17− weak var vcProfile: ProfileViewController?
18−
19−
20− override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
21− super.init(style: style, reuseIdentifier: reuseIdentifier)
22− backgroundColor = .white
23− setUpCell()
24− }
25−
26− required init?(coder aDecoder: NSCoder) {
27− super.init(coder: aDecoder)
28− }
29−
30− func setUpCell(){
31−
32− addSubview(postsChannelsSegment)
33− postsChannelsSegment.selectedSegmentIndex = 0
34− postsChannelsSegment.addTarget(self, action: #selector(changedValue), for: .valueChanged)
35− postsChannelsSegment.edgesToSuperview(insets: .left(16) + .right(16) + .top(8) + .bottom(8))
36− }
37−
38− // Initialize
39− var postsChannelsSegment: UISegmentedControl = UISegmentedControl(items: ["Posts", "Channels"])
40−
41− @objc func changedValue(_ sender: UISegmentedControl) {
42− let index = sender.selectedSegmentIndex
43−
44− switch index {
45− case 0:
46− vc?.setUpNavigationItemsforPosts()
47− case 1:
48− vc?.setUpNavigationItemsForChannels()
49− default:
50− break
51− }
52− }
53−}
54−
GDproject/Controller/BasicInfoCell.swift → GDproject/Controller/Profile/BasicInfoCell.swiftrenamed

The content is the same.

GDproject/Controller/BasicInfoController.swift → GDproject/Controller/Profile/BasicInfoController.swiftrenamed

The content is the same.

GDproject/Controller/InfoCell.swift → GDproject/Controller/Profile/InfoCell.swiftrenamed

The content is the same.

GDproject/Controller/InviteViewController.swift → GDproject/Controller/Profile/InviteViewController.swiftrenamed

The content is the same.

GDproject/Controller/ProfileViewController.swift → GDproject/Controller/Profile/ProfileViewController.swiftrenamed+2−3
@@ -48,15 +48,14 @@ class ProfileViewController: UIViewController
48 {
48 {
49 super.viewDidLoad()
49 super.viewDidLoad()
50
50
51− posts.type = .NONE
52−
53 posts.dataSourse = [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 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. comme Aldus PageMaker. est qu'il possède une distribution de lettres plus ou moins normale, et en tout cas comparable avec celle du français standard. De nombreuses suites logicielles de mise en page ou éditeurs de sites Web ont fait du Lorem Ipsum leur faux texte par défaut, et une recherche pour 'Lorem Ipsum' vous conduira vers de nombreux sites qui n'en sont encore qu'à leur phase de construction. Plusieurs versions sont apparues avec le temps, parfois par accident, souvent intentionnellement (histoire d'y rajouter de petits clins d'oeil, voire des phrases embarassantes).")]), Post(dataArray: [.text("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é. Il a été popularisé dans les années 1960 grâce à la vente de feuilles Letraset contenant des passages du Lorem Ipsum, et, plus récemment, par son inclusion dans des applications de mise en page de texte, comme Aldus PageMaker. .")])]
51 posts.dataSourse = [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 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. comme Aldus PageMaker. est qu'il possède une distribution de lettres plus ou moins normale, et en tout cas comparable avec celle du français standard. De nombreuses suites logicielles de mise en page ou éditeurs de sites Web ont fait du Lorem Ipsum leur faux texte par défaut, et une recherche pour 'Lorem Ipsum' vous conduira vers de nombreux sites qui n'en sont encore qu'à leur phase de construction. Plusieurs versions sont apparues avec le temps, parfois par accident, souvent intentionnellement (histoire d'y rajouter de petits clins d'oeil, voire des phrases embarassantes).")]), Post(dataArray: [.text("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é. Il a été popularisé dans les années 1960 grâce à la vente de feuilles Letraset contenant des passages du Lorem Ipsum, et, plus récemment, par son inclusion dans des applications de mise en page de texte, comme Aldus PageMaker. .")])]
54
52
55 // basicInfo.dataSourse =
53 // basicInfo.dataSourse =
56
54
57 posts.viewController = self
55 posts.viewController = self
56+ posts.type = .NONE
58
57
59− tableView.register(HeaderNewsChannels.self, forCellReuseIdentifier: headerNewsChannelsVC)
58+ tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell")
60
59
61 tableView.register(PostViewCell.self, forCellReuseIdentifier: postCellId)
60 tableView.register(PostViewCell.self, forCellReuseIdentifier: postCellId)
62
61
GDproject/Controller/SettingsViewController.swift → GDproject/Controller/Profile/SettingsViewController.swiftrenamed

The content is the same.

GDproject/DataStorage.swiftnew file+45
@@ -0,0 +1,45 @@
1+//
2+// DataStorage.swift
3+// GDproject
4+//
5+// Created by cstore on 21/02/2019.
6+// Copyright © 2019 drHSE. All rights reserved.
7+//
8+
9+import Foundation
10+
11+/**
12+ _DataStorage_ class is aimed to store user private settings
13+ to display correct data after user leaving the app
14+ */
15+class DataStorage{
16+
17+ private init(){}
18+
19+ static let standard = DataStorage()
20+
21+ // add channel
22+
23+ // delete channel
24+
25+ /**
26+ Function for setting log in status of user
27+ */
28+ func setIsLoggedIn(value: Bool){
29+ UserDefaults.standard.set(value, forKey: UserDefaultsKeys.loggedIn.rawValue)
30+ }
31+
32+ /**
33+ Function to determine is user logged in already or not
34+ */
35+ func isLoggedIn() -> Bool {
36+ return UserDefaults.standard.bool(forKey: UserDefaultsKeys.loggedIn.rawValue)
37+ }
38+}
39+
40+/**
41+ Enum to store UserDefaults keys for getting and setting values
42+ */
43+enum UserDefaultsKeys: String{
44+ case loggedIn
45+}
GDproject/Extentions.swift+22
@@ -34,3 +34,25 @@ extension UIView
34 addConstraints(NSLayoutConstraint.constraints(withVisualFormat: format, options: NSLayoutConstraint.FormatOptions(), metrics: nil, views: viewsDictionary))
34 addConstraints(NSLayoutConstraint.constraints(withVisualFormat: format, options: NSLayoutConstraint.FormatOptions(), metrics: nil, views: viewsDictionary))
35 }
35 }
36}
36}
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+
51+ class func tabBarController() -> UITabBarController{
52+ return UIStoryboard.userEdit.instantiateViewController(withIdentifier: "TabBar") as! UITabBarController
53+ }
54+
55+ class func navChannels() ->UINavigationController{
56+ return UIStoryboard.userEdit.instantiateViewController(withIdentifier: "navChannels") as! UINavigationController
57+ }
58+}
GDproject/MainController.swiftnew file+44
@@ -0,0 +1,44 @@
1+//
2+// MainController.swift
3+// GDproject
4+//
5+// Created by cstore on 21/02/2019.
6+// Copyright © 2019 drHSE. All rights reserved.
7+//
8+
9+import UIKit
10+
11+class MainController: UINavigationController {
12+
13+ override func viewDidLoad() {
14+ super.viewDidLoad()
15+
16+// if false {
17+// perform(#selector(showLogInController), with: nil, afterDelay: 0.01)
18+// } else {
19+// perform(#selector(fhfh), with: nil, afterDelay: 0.01)
20+//
21+// }
22+ }
23+
24+// @objc func showLogInController(){
25+// let vc = storyboard!.instantiateViewController(withIdentifier: logInController) as! LogInViewController
26+// present(vc, animated: true) {
27+// print("opportunity to log in")
28+// }
29+// }
30+
31+// @objc func fhfh(){
32+//
33+// let newsController = NC()
34+// viewControllers = [newsController]
35+// }
36+// override func viewDidAppear(_ animated: Bool) {
37+// super.viewDidAppear(animated)
38+//
39+//
40+// }
41+}
42+
43+
44+
GDproject/Simple model/Channel.swiftnew file+35
@@ -0,0 +1,35 @@
1+//
2+// Channel.swift
3+// GDproject
4+//
5+// Created by cstore on 20/02/2019.
6+// Copyright © 2019 drHSE. All rights reserved.
7+//
8+
9+import Foundation
10+
11+class Channel: Equatable {
12+ static func == (lhs: Channel, rhs: Channel) -> Bool {
13+ return (lhs.title == rhs.title &&
14+ lhs.subtitle == rhs.subtitle &&
15+ lhs.people == rhs.people &&
16+ lhs.hashtags == rhs.hashtags)
17+ }
18+
19+ var title = String()
20+ var subtitle = String()
21+
22+ var hashtags: [String] = []
23+ var people: [String] = []
24+
25+ var posts: [Post] = []
26+
27+ init(title: String, subtitle: String, hashtags: [String], people: [String], posts: [Post])
28+ {
29+ self.title = title
30+ self.subtitle = subtitle
31+ self.people = people
32+ self.hashtags = hashtags
33+ self.posts = posts
34+ }
35+}
GDproject/Supporting files/AppDelegate.swift+17−5
@@ -11,11 +11,25 @@ import UIKit
11@UIApplicationMain
11@UIApplicationMain
12class AppDelegate: UIResponder, UIApplicationDelegate {
12class AppDelegate: UIResponder, UIApplicationDelegate {
13
13
14+ var coordinator: ChannelsCoordinator!
15+ var tabCoordinator: TabbarCoordinator!
16+
14 var window: UIWindow?
17 var window: UIWindow?
18+ var rootController: UINavigationController? {
19+ return self.window!.rootViewController as? UINavigationController
20+ }
15
21
16−
22+ private func makeCoordinator(with: UINavigationController) -> ChannelsCoordinator {
23+ return ChannelsCoordinator(currentChannel: Channel(title: "example", subtitle: "ex", hashtags: ["none"], people: ["none"], posts: []), navigationController: with)
24+ }
25+
17− func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
26+ func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool
18− // Override point for customization after application launch.
27+ {
28+
29+ // TODO:- determine what to do here: log in or tabbar
30+ tabCoordinator = TabbarCoordinator(window: window!)
31+ tabCoordinator.start()
32+
19 return true
33 return true
20 }
34 }
21
35
@@ -40,7 +54,5 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
40 func applicationWillTerminate(_ application: UIApplication) {
54 func applicationWillTerminate(_ application: UIApplication) {
41 // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
55 // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
42 }
56 }
43−
44−
45}
57}
46
58
GDproject/Supporting files/Base.lproj/LaunchScreen.storyboard+7−3
@@ -1,7 +1,11 @@
1−<?xml version="1.0" encoding="UTF-8" standalone="no"?>
1+<?xml version="1.0" encoding="UTF-8"?>
2−<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="13122.16" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
2+<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="14460.31" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
3+ <device id="retina4_7" orientation="portrait">
4+ <adaptation id="fullscreen"/>
5+ </device>
3 <dependencies>
6 <dependencies>
7+ <deployment identifier="iOS"/>
4− <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13104.12"/>
8+ <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14460.20"/>
5 <capability name="Safe area layout guides" minToolsVersion="9.0"/>
9 <capability name="Safe area layout guides" minToolsVersion="9.0"/>
6 <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
10 <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
7 </dependencies>
11 </dependencies>