git.iko.soy/dashared/GDproject
on master help sign in
Version 0.1 : news feed

gradient, crop post content, create post, markdown

commit3c5c062177f9ddb057e638aa9a6c5ed8ac727ad0 authorDarya Rednikina <31587869+dashared@users.noreply.github.com> dateFri 15 Feb 2019, 16:29 (8 years ago) parent75aa884
22 files changed+1748
Cartfile+5 GDproject.xcodeproj/project.pbxproj+469 GDproject.xcodeproj/project.xcworkspace/contents.xcworkspacedata+7 GDproject.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist+8 GDproject/Base.lproj/Main.storyboard+112 GDproject/Constants.swift+14 GDproject/Controller/ChannelsController.swift+15 GDproject/Controller/FullPostController.swift+133 GDproject/Controller/HeaderNewsChannels.swift+56 GDproject/Controller/MyStackView.swift+27 GDproject/Controller/NewPostViewController.swift+257 GDproject/Controller/News/PostViewCell.swift+121 GDproject/Controller/NewsController.swift+204 GDproject/Info.plist+45 GDproject/Simple model/Post.swift+39 GDproject/Simple model/User.swift+40 GDproject/Supporting files/AppDelegate.swift+46 GDproject/Supporting files/Assets.xcassets/AppIcon.appiconset/Contents.json+98 GDproject/Supporting files/Assets.xcassets/Contents.json+6 GDproject/Supporting files/Assets.xcassets/icons8-share-3-500.imageset/Contents.json+21 GDproject/Supporting files/Assets.xcassets/icons8-share-3-500.imageset/icons8-share-3-500.png GDproject/Supporting files/Base.lproj/LaunchScreen.storyboard+25
Cartfilenew file+5
@@ -0,0 +1,5 @@
1+github "robb/Cartography"
2+github "ivanbruel/MarkdownKit"
3+github "roberthein/TinyConstraints"
4+github "macteo/Marklight"
5+github "ElaWorkshop/TagListView"
GDproject.xcodeproj/project.pbxprojnew file+469
@@ -0,0 +1,469 @@
1+// !$*UTF8*$!
2+{
3+ archiveVersion = 1;
4+ classes = {
5+ };
6+ objectVersion = 50;
7+ objects = {
8+
9+/* Begin PBXBuildFile section */
10+ 12E36D9C221424EA006FCDD7 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12E36D9B221424EA006FCDD7 /* AppDelegate.swift */; };
11+ 12E36D9E221424EA006FCDD7 /* NewsController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12E36D9D221424EA006FCDD7 /* NewsController.swift */; };
12+ 12E36DA1221424EA006FCDD7 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 12E36D9F221424EA006FCDD7 /* Main.storyboard */; };
13+ 12E36DA3221424ED006FCDD7 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 12E36DA2221424ED006FCDD7 /* Assets.xcassets */; };
14+ 12E36DA6221424ED006FCDD7 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 12E36DA4221424ED006FCDD7 /* LaunchScreen.storyboard */; };
15+ 12E36DAF22143D40006FCDD7 /* Cartography.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 12E36DAE22143D40006FCDD7 /* Cartography.framework */; };
16+ 12E36DB322143D4E006FCDD7 /* Marklight.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 12E36DB222143D4E006FCDD7 /* Marklight.framework */; };
17+ 12E36DB522143D54006FCDD7 /* TinyConstraints.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 12E36DB422143D54006FCDD7 /* TinyConstraints.framework */; };
18+ 12E36DB72214400A006FCDD7 /* Post.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12E36DB62214400A006FCDD7 /* Post.swift */; };
19+ 12E36DB922144016006FCDD7 /* User.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12E36DB822144016006FCDD7 /* User.swift */; };
20+ 12E36DBD221441D5006FCDD7 /* TinyConstraints.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 12E36DB422143D54006FCDD7 /* TinyConstraints.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
21+ 12E36DC0221441DB006FCDD7 /* Marklight.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 12E36DB222143D4E006FCDD7 /* Marklight.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
22+ 12E36DC2221441E1006FCDD7 /* MarkdownKit.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 12E36DB022143D47006FCDD7 /* MarkdownKit.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
23+ 12E36DC4221441EA006FCDD7 /* Cartography.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 12E36DAE22143D40006FCDD7 /* Cartography.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
24+ 12E36DC622144266006FCDD7 /* HeaderNewsChannels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12E36DC522144266006FCDD7 /* HeaderNewsChannels.swift */; };
25+ 12E36DC822144374006FCDD7 /* ChannelsController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12E36DC722144374006FCDD7 /* ChannelsController.swift */; };
26+ 12E36DCA22144635006FCDD7 /* NewPostViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12E36DC922144635006FCDD7 /* NewPostViewController.swift */; };
27+ 12E36DCC22144725006FCDD7 /* PostViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12E36DCB22144725006FCDD7 /* PostViewCell.swift */; };
28+ 12E36DCE22144756006FCDD7 /* Constants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12E36DCD22144756006FCDD7 /* Constants.swift */; };
29+ 12E36DD122148122006FCDD7 /* FullPostController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12E36DD022148122006FCDD7 /* FullPostController.swift */; };
30+ 12E36DD522156559006FCDD7 /* MyStackView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12E36DD422156559006FCDD7 /* MyStackView.swift */; };
31+ 12E36DD8221594A9006FCDD7 /* TagListView.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 12E36DD622159493006FCDD7 /* TagListView.framework */; };
32+ 12E36DD9221594A9006FCDD7 /* TagListView.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 12E36DD622159493006FCDD7 /* TagListView.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
33+ 12E36DDB221594B1006FCDD7 /* MarkdownKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 12E36DB022143D47006FCDD7 /* MarkdownKit.framework */; };
34+/* End PBXBuildFile section */
35+
36+/* Begin PBXCopyFilesBuildPhase section */
37+ 12E36DBE221441D5006FCDD7 /* Embed Frameworks */ = {
38+ isa = PBXCopyFilesBuildPhase;
39+ buildActionMask = 2147483647;
40+ dstPath = "";
41+ dstSubfolderSpec = 10;
42+ files = (
43+ 12E36DC0221441DB006FCDD7 /* Marklight.framework in Embed Frameworks */,
44+ 12E36DC4221441EA006FCDD7 /* Cartography.framework in Embed Frameworks */,
45+ 12E36DD9221594A9006FCDD7 /* TagListView.framework in Embed Frameworks */,
46+ 12E36DBD221441D5006FCDD7 /* TinyConstraints.framework in Embed Frameworks */,
47+ 12E36DC2221441E1006FCDD7 /* MarkdownKit.framework in Embed Frameworks */,
48+ );
49+ name = "Embed Frameworks";
50+ runOnlyForDeploymentPostprocessing = 0;
51+ };
52+/* End PBXCopyFilesBuildPhase section */
53+
54+/* Begin PBXFileReference section */
55+ 12E36D98221424EA006FCDD7 /* GDproject.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = GDproject.app; sourceTree = BUILT_PRODUCTS_DIR; };
56+ 12E36D9B221424EA006FCDD7 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
57+ 12E36D9D221424EA006FCDD7 /* NewsController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewsController.swift; sourceTree = "<group>"; };
58+ 12E36DA0221424EA006FCDD7 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
59+ 12E36DA2221424ED006FCDD7 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
60+ 12E36DA5221424ED006FCDD7 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
61+ 12E36DA7221424ED006FCDD7 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
62+ 12E36DAE22143D40006FCDD7 /* Cartography.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cartography.framework; path = Carthage/Build/iOS/Cartography.framework; sourceTree = "<group>"; };
63+ 12E36DB022143D47006FCDD7 /* MarkdownKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MarkdownKit.framework; path = Carthage/Build/iOS/MarkdownKit.framework; sourceTree = "<group>"; };
64+ 12E36DB222143D4E006FCDD7 /* Marklight.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Marklight.framework; path = Carthage/Build/iOS/Marklight.framework; sourceTree = "<group>"; };
65+ 12E36DB422143D54006FCDD7 /* TinyConstraints.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = TinyConstraints.framework; path = Carthage/Build/iOS/TinyConstraints.framework; sourceTree = "<group>"; };
66+ 12E36DB62214400A006FCDD7 /* Post.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Post.swift; sourceTree = "<group>"; };
67+ 12E36DB822144016006FCDD7 /* User.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = User.swift; sourceTree = "<group>"; };
68+ 12E36DC522144266006FCDD7 /* HeaderNewsChannels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HeaderNewsChannels.swift; sourceTree = "<group>"; };
69+ 12E36DC722144374006FCDD7 /* ChannelsController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChannelsController.swift; sourceTree = "<group>"; };
70+ 12E36DC922144635006FCDD7 /* NewPostViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewPostViewController.swift; sourceTree = "<group>"; };
71+ 12E36DCB22144725006FCDD7 /* PostViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PostViewCell.swift; sourceTree = "<group>"; };
72+ 12E36DCD22144756006FCDD7 /* Constants.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Constants.swift; sourceTree = "<group>"; };
73+ 12E36DD022148122006FCDD7 /* FullPostController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FullPostController.swift; sourceTree = "<group>"; };
74+ 12E36DD422156559006FCDD7 /* MyStackView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MyStackView.swift; sourceTree = "<group>"; };
75+ 12E36DD622159493006FCDD7 /* TagListView.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = TagListView.framework; path = Carthage/Build/iOS/TagListView.framework; sourceTree = "<group>"; };
76+/* End PBXFileReference section */
77+
78+/* Begin PBXFrameworksBuildPhase section */
79+ 12E36D95221424EA006FCDD7 /* Frameworks */ = {
80+ isa = PBXFrameworksBuildPhase;
81+ buildActionMask = 2147483647;
82+ files = (
83+ 12E36DB522143D54006FCDD7 /* TinyConstraints.framework in Frameworks */,
84+ 12E36DDB221594B1006FCDD7 /* MarkdownKit.framework in Frameworks */,
85+ 12E36DD8221594A9006FCDD7 /* TagListView.framework in Frameworks */,
86+ 12E36DAF22143D40006FCDD7 /* Cartography.framework in Frameworks */,
87+ 12E36DB322143D4E006FCDD7 /* Marklight.framework in Frameworks */,
88+ );
89+ runOnlyForDeploymentPostprocessing = 0;
90+ };
91+/* End PBXFrameworksBuildPhase section */
92+
93+/* Begin PBXGroup section */
94+ 12E36D8F221424EA006FCDD7 = {
95+ isa = PBXGroup;
96+ children = (
97+ 12E36DD622159493006FCDD7 /* TagListView.framework */,
98+ 12E36DB422143D54006FCDD7 /* TinyConstraints.framework */,
99+ 12E36DB222143D4E006FCDD7 /* Marklight.framework */,
100+ 12E36DB022143D47006FCDD7 /* MarkdownKit.framework */,
101+ 12E36DAE22143D40006FCDD7 /* Cartography.framework */,
102+ 12E36D9A221424EA006FCDD7 /* GDproject */,
103+ 12E36D99221424EA006FCDD7 /* Products */,
104+ 12E36DDA221594B1006FCDD7 /* Frameworks */,
105+ );
106+ sourceTree = "<group>";
107+ };
108+ 12E36D99221424EA006FCDD7 /* Products */ = {
109+ isa = PBXGroup;
110+ children = (
111+ 12E36D98221424EA006FCDD7 /* GDproject.app */,
112+ );
113+ name = Products;
114+ sourceTree = "<group>";
115+ };
116+ 12E36D9A221424EA006FCDD7 /* GDproject */ = {
117+ isa = PBXGroup;
118+ children = (
119+ 12E36DCF22145923006FCDD7 /* Controller */,
120+ 12E36DCD22144756006FCDD7 /* Constants.swift */,
121+ 12E36DBB2214402B006FCDD7 /* Supporting files */,
122+ 12E36DBA2214401B006FCDD7 /* Simple model */,
123+ 12E36D9F221424EA006FCDD7 /* Main.storyboard */,
124+ 12E36DA7221424ED006FCDD7 /* Info.plist */,
125+ );
126+ path = GDproject;
127+ sourceTree = "<group>";
128+ };
129+ 12E36DBA2214401B006FCDD7 /* Simple model */ = {
130+ isa = PBXGroup;
131+ children = (
132+ 12E36DB62214400A006FCDD7 /* Post.swift */,
133+ 12E36DB822144016006FCDD7 /* User.swift */,
134+ );
135+ path = "Simple model";
136+ sourceTree = "<group>";
137+ };
138+ 12E36DBB2214402B006FCDD7 /* Supporting files */ = {
139+ isa = PBXGroup;
140+ children = (
141+ 12E36D9B221424EA006FCDD7 /* AppDelegate.swift */,
142+ 12E36DA2221424ED006FCDD7 /* Assets.xcassets */,
143+ 12E36DA4221424ED006FCDD7 /* LaunchScreen.storyboard */,
144+ );
145+ path = "Supporting files";
146+ sourceTree = "<group>";
147+ };
148+ 12E36DCF22145923006FCDD7 /* Controller */ = {
149+ isa = PBXGroup;
150+ children = (
151+ 12E36DD422156559006FCDD7 /* MyStackView.swift */,
152+ 12E36DD022148122006FCDD7 /* FullPostController.swift */,
153+ 12E36DC522144266006FCDD7 /* HeaderNewsChannels.swift */,
154+ 12E36DC722144374006FCDD7 /* ChannelsController.swift */,
155+ 12E36D9D221424EA006FCDD7 /* NewsController.swift */,
156+ 12E36DD322156519006FCDD7 /* News */,
157+ 12E36DC922144635006FCDD7 /* NewPostViewController.swift */,
158+ );
159+ path = Controller;
160+ sourceTree = "<group>";
161+ };
162+ 12E36DD322156519006FCDD7 /* News */ = {
163+ isa = PBXGroup;
164+ children = (
165+ 12E36DCB22144725006FCDD7 /* PostViewCell.swift */,
166+ );
167+ path = News;
168+ sourceTree = "<group>";
169+ };
170+ 12E36DDA221594B1006FCDD7 /* Frameworks */ = {
171+ isa = PBXGroup;
172+ children = (
173+ );
174+ name = Frameworks;
175+ sourceTree = "<group>";
176+ };
177+/* End PBXGroup section */
178+
179+/* Begin PBXNativeTarget section */
180+ 12E36D97221424EA006FCDD7 /* GDproject */ = {
181+ isa = PBXNativeTarget;
182+ buildConfigurationList = 12E36DAA221424ED006FCDD7 /* Build configuration list for PBXNativeTarget "GDproject" */;
183+ buildPhases = (
184+ 12E36D94221424EA006FCDD7 /* Sources */,
185+ 12E36D95221424EA006FCDD7 /* Frameworks */,
186+ 12E36D96221424EA006FCDD7 /* Resources */,
187+ 12E36DBE221441D5006FCDD7 /* Embed Frameworks */,
188+ );
189+ buildRules = (
190+ );
191+ dependencies = (
192+ );
193+ name = GDproject;
194+ productName = GDproject;
195+ productReference = 12E36D98221424EA006FCDD7 /* GDproject.app */;
196+ productType = "com.apple.product-type.application";
197+ };
198+/* End PBXNativeTarget section */
199+
200+/* Begin PBXProject section */
201+ 12E36D90221424EA006FCDD7 /* Project object */ = {
202+ isa = PBXProject;
203+ attributes = {
204+ LastSwiftUpdateCheck = 1010;
205+ LastUpgradeCheck = 1010;
206+ ORGANIZATIONNAME = drHSE;
207+ TargetAttributes = {
208+ 12E36D97221424EA006FCDD7 = {
209+ CreatedOnToolsVersion = 10.1;
210+ };
211+ };
212+ };
213+ buildConfigurationList = 12E36D93221424EA006FCDD7 /* Build configuration list for PBXProject "GDproject" */;
214+ compatibilityVersion = "Xcode 9.3";
215+ developmentRegion = en;
216+ hasScannedForEncodings = 0;
217+ knownRegions = (
218+ en,
219+ Base,
220+ );
221+ mainGroup = 12E36D8F221424EA006FCDD7;
222+ productRefGroup = 12E36D99221424EA006FCDD7 /* Products */;
223+ projectDirPath = "";
224+ projectRoot = "";
225+ targets = (
226+ 12E36D97221424EA006FCDD7 /* GDproject */,
227+ );
228+ };
229+/* End PBXProject section */
230+
231+/* Begin PBXResourcesBuildPhase section */
232+ 12E36D96221424EA006FCDD7 /* Resources */ = {
233+ isa = PBXResourcesBuildPhase;
234+ buildActionMask = 2147483647;
235+ files = (
236+ 12E36DA6221424ED006FCDD7 /* LaunchScreen.storyboard in Resources */,
237+ 12E36DA3221424ED006FCDD7 /* Assets.xcassets in Resources */,
238+ 12E36DA1221424EA006FCDD7 /* Main.storyboard in Resources */,
239+ );
240+ runOnlyForDeploymentPostprocessing = 0;
241+ };
242+/* End PBXResourcesBuildPhase section */
243+
244+/* Begin PBXSourcesBuildPhase section */
245+ 12E36D94221424EA006FCDD7 /* Sources */ = {
246+ isa = PBXSourcesBuildPhase;
247+ buildActionMask = 2147483647;
248+ files = (
249+ 12E36DD522156559006FCDD7 /* MyStackView.swift in Sources */,
250+ 12E36DC822144374006FCDD7 /* ChannelsController.swift in Sources */,
251+ 12E36DB922144016006FCDD7 /* User.swift in Sources */,
252+ 12E36DB72214400A006FCDD7 /* Post.swift in Sources */,
253+ 12E36DCA22144635006FCDD7 /* NewPostViewController.swift in Sources */,
254+ 12E36D9E221424EA006FCDD7 /* NewsController.swift in Sources */,
255+ 12E36DC622144266006FCDD7 /* HeaderNewsChannels.swift in Sources */,
256+ 12E36DCC22144725006FCDD7 /* PostViewCell.swift in Sources */,
257+ 12E36DD122148122006FCDD7 /* FullPostController.swift in Sources */,
258+ 12E36D9C221424EA006FCDD7 /* AppDelegate.swift in Sources */,
259+ 12E36DCE22144756006FCDD7 /* Constants.swift in Sources */,
260+ );
261+ runOnlyForDeploymentPostprocessing = 0;
262+ };
263+/* End PBXSourcesBuildPhase section */
264+
265+/* Begin PBXVariantGroup section */
266+ 12E36D9F221424EA006FCDD7 /* Main.storyboard */ = {
267+ isa = PBXVariantGroup;
268+ children = (
269+ 12E36DA0221424EA006FCDD7 /* Base */,
270+ );
271+ name = Main.storyboard;
272+ sourceTree = "<group>";
273+ };
274+ 12E36DA4221424ED006FCDD7 /* LaunchScreen.storyboard */ = {
275+ isa = PBXVariantGroup;
276+ children = (
277+ 12E36DA5221424ED006FCDD7 /* Base */,
278+ );
279+ name = LaunchScreen.storyboard;
280+ sourceTree = "<group>";
281+ };
282+/* End PBXVariantGroup section */
283+
284+/* Begin XCBuildConfiguration section */
285+ 12E36DA8221424ED006FCDD7 /* Debug */ = {
286+ isa = XCBuildConfiguration;
287+ buildSettings = {
288+ ALWAYS_SEARCH_USER_PATHS = NO;
289+ CLANG_ANALYZER_NONNULL = YES;
290+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
291+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
292+ CLANG_CXX_LIBRARY = "libc++";
293+ CLANG_ENABLE_MODULES = YES;
294+ CLANG_ENABLE_OBJC_ARC = YES;
295+ CLANG_ENABLE_OBJC_WEAK = YES;
296+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
297+ CLANG_WARN_BOOL_CONVERSION = YES;
298+ CLANG_WARN_COMMA = YES;
299+ CLANG_WARN_CONSTANT_CONVERSION = YES;
300+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
301+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
302+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
303+ CLANG_WARN_EMPTY_BODY = YES;
304+ CLANG_WARN_ENUM_CONVERSION = YES;
305+ CLANG_WARN_INFINITE_RECURSION = YES;
306+ CLANG_WARN_INT_CONVERSION = YES;
307+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
308+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
309+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
310+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
311+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
312+ CLANG_WARN_STRICT_PROTOTYPES = YES;
313+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
314+ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
315+ CLANG_WARN_UNREACHABLE_CODE = YES;
316+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
317+ CODE_SIGN_IDENTITY = "iPhone Developer";
318+ COPY_PHASE_STRIP = NO;
319+ DEBUG_INFORMATION_FORMAT = dwarf;
320+ ENABLE_STRICT_OBJC_MSGSEND = YES;
321+ ENABLE_TESTABILITY = YES;
322+ GCC_C_LANGUAGE_STANDARD = gnu11;
323+ GCC_DYNAMIC_NO_PIC = NO;
324+ GCC_NO_COMMON_BLOCKS = YES;
325+ GCC_OPTIMIZATION_LEVEL = 0;
326+ GCC_PREPROCESSOR_DEFINITIONS = (
327+ "DEBUG=1",
328+ "$(inherited)",
329+ );
330+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
331+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
332+ GCC_WARN_UNDECLARED_SELECTOR = YES;
333+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
334+ GCC_WARN_UNUSED_FUNCTION = YES;
335+ GCC_WARN_UNUSED_VARIABLE = YES;
336+ IPHONEOS_DEPLOYMENT_TARGET = 12.1;
337+ MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
338+ MTL_FAST_MATH = YES;
339+ ONLY_ACTIVE_ARCH = YES;
340+ SDKROOT = iphoneos;
341+ SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
342+ SWIFT_OPTIMIZATION_LEVEL = "-Onone";
343+ };
344+ name = Debug;
345+ };
346+ 12E36DA9221424ED006FCDD7 /* Release */ = {
347+ isa = XCBuildConfiguration;
348+ buildSettings = {
349+ ALWAYS_SEARCH_USER_PATHS = NO;
350+ CLANG_ANALYZER_NONNULL = YES;
351+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
352+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
353+ CLANG_CXX_LIBRARY = "libc++";
354+ CLANG_ENABLE_MODULES = YES;
355+ CLANG_ENABLE_OBJC_ARC = YES;
356+ CLANG_ENABLE_OBJC_WEAK = YES;
357+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
358+ CLANG_WARN_BOOL_CONVERSION = YES;
359+ CLANG_WARN_COMMA = YES;
360+ CLANG_WARN_CONSTANT_CONVERSION = YES;
361+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
362+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
363+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
364+ CLANG_WARN_EMPTY_BODY = YES;
365+ CLANG_WARN_ENUM_CONVERSION = YES;
366+ CLANG_WARN_INFINITE_RECURSION = YES;
367+ CLANG_WARN_INT_CONVERSION = YES;
368+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
369+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
370+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
371+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
372+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
373+ CLANG_WARN_STRICT_PROTOTYPES = YES;
374+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
375+ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
376+ CLANG_WARN_UNREACHABLE_CODE = YES;
377+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
378+ CODE_SIGN_IDENTITY = "iPhone Developer";
379+ COPY_PHASE_STRIP = NO;
380+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
381+ ENABLE_NS_ASSERTIONS = NO;
382+ ENABLE_STRICT_OBJC_MSGSEND = YES;
383+ GCC_C_LANGUAGE_STANDARD = gnu11;
384+ GCC_NO_COMMON_BLOCKS = YES;
385+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
386+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
387+ GCC_WARN_UNDECLARED_SELECTOR = YES;
388+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
389+ GCC_WARN_UNUSED_FUNCTION = YES;
390+ GCC_WARN_UNUSED_VARIABLE = YES;
391+ IPHONEOS_DEPLOYMENT_TARGET = 12.1;
392+ MTL_ENABLE_DEBUG_INFO = NO;
393+ MTL_FAST_MATH = YES;
394+ SDKROOT = iphoneos;
395+ SWIFT_COMPILATION_MODE = wholemodule;
396+ SWIFT_OPTIMIZATION_LEVEL = "-O";
397+ VALIDATE_PRODUCT = YES;
398+ };
399+ name = Release;
400+ };
401+ 12E36DAB221424ED006FCDD7 /* Debug */ = {
402+ isa = XCBuildConfiguration;
403+ buildSettings = {
404+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
405+ CODE_SIGN_STYLE = Automatic;
406+ DEVELOPMENT_TEAM = 9Z6LFGKA9G;
407+ FRAMEWORK_SEARCH_PATHS = (
408+ "$(inherited)",
409+ "$(PROJECT_DIR)/Carthage/Build/iOS",
410+ );
411+ INFOPLIST_FILE = GDproject/Info.plist;
412+ LD_RUNPATH_SEARCH_PATHS = (
413+ "$(inherited)",
414+ "@executable_path/Frameworks",
415+ );
416+ PRODUCT_BUNDLE_IDENTIFIER = rednikina.com.drHSE.GDproject;
417+ PRODUCT_NAME = "$(TARGET_NAME)";
418+ SWIFT_VERSION = 4.2;
419+ TARGETED_DEVICE_FAMILY = "1,2";
420+ };
421+ name = Debug;
422+ };
423+ 12E36DAC221424ED006FCDD7 /* Release */ = {
424+ isa = XCBuildConfiguration;
425+ buildSettings = {
426+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
427+ CODE_SIGN_STYLE = Automatic;
428+ DEVELOPMENT_TEAM = 9Z6LFGKA9G;
429+ FRAMEWORK_SEARCH_PATHS = (
430+ "$(inherited)",
431+ "$(PROJECT_DIR)/Carthage/Build/iOS",
432+ );
433+ INFOPLIST_FILE = GDproject/Info.plist;
434+ LD_RUNPATH_SEARCH_PATHS = (
435+ "$(inherited)",
436+ "@executable_path/Frameworks",
437+ );
438+ PRODUCT_BUNDLE_IDENTIFIER = rednikina.com.drHSE.GDproject;
439+ PRODUCT_NAME = "$(TARGET_NAME)";
440+ SWIFT_VERSION = 4.2;
441+ TARGETED_DEVICE_FAMILY = "1,2";
442+ };
443+ name = Release;
444+ };
445+/* End XCBuildConfiguration section */
446+
447+/* Begin XCConfigurationList section */
448+ 12E36D93221424EA006FCDD7 /* Build configuration list for PBXProject "GDproject" */ = {
449+ isa = XCConfigurationList;
450+ buildConfigurations = (
451+ 12E36DA8221424ED006FCDD7 /* Debug */,
452+ 12E36DA9221424ED006FCDD7 /* Release */,
453+ );
454+ defaultConfigurationIsVisible = 0;
455+ defaultConfigurationName = Release;
456+ };
457+ 12E36DAA221424ED006FCDD7 /* Build configuration list for PBXNativeTarget "GDproject" */ = {
458+ isa = XCConfigurationList;
459+ buildConfigurations = (
460+ 12E36DAB221424ED006FCDD7 /* Debug */,
461+ 12E36DAC221424ED006FCDD7 /* Release */,
462+ );
463+ defaultConfigurationIsVisible = 0;
464+ defaultConfigurationName = Release;
465+ };
466+/* End XCConfigurationList section */
467+ };
468+ rootObject = 12E36D90221424EA006FCDD7 /* Project object */;
469+}
GDproject.xcodeproj/project.xcworkspace/contents.xcworkspacedatanew file+7
@@ -0,0 +1,7 @@
1+<?xml version="1.0" encoding="UTF-8"?>
2+<Workspace
3+ version = "1.0">
4+ <FileRef
5+ location = "self:GDproject.xcodeproj">
6+ </FileRef>
7+</Workspace>
GDproject.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plistnew file+8
@@ -0,0 +1,8 @@
1+<?xml version="1.0" encoding="UTF-8"?>
2+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3+<plist version="1.0">
4+<dict>
5+ <key>IDEDidComputeMac32BitWarning</key>
6+ <true/>
7+</dict>
8+</plist>
GDproject/Base.lproj/Main.storyboardnew file+112
@@ -0,0 +1,112 @@
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="NuV-ZG-ld2">
3+ <device id="retina4_7" orientation="portrait">
4+ <adaptation id="fullscreen"/>
5+ </device>
6+ <dependencies>
7+ <deployment identifier="iOS"/>
8+ <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14460.20"/>
9+ <capability name="Safe area layout guides" minToolsVersion="9.0"/>
10+ <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
11+ </dependencies>
12+ <scenes>
13+ <!--News Controller-->
14+ <scene sceneID="tne-QT-ifu">
15+ <objects>
16+ <viewController id="BYZ-38-t0r" customClass="NewsController" customModule="GDproject" customModuleProvider="target" sceneMemberID="viewController">
17+ <view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
18+ <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
19+ <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
20+ <subviews>
21+ <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">
22+ <rect key="frame" x="0.0" y="116" width="375" height="551"/>
23+ <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
24+ </tableView>
25+ </subviews>
26+ <color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
27+ <constraints>
28+ <constraint firstItem="bdn-EE-6KU" firstAttribute="leading" secondItem="6Tk-OE-BBY" secondAttribute="leading" id="Mwc-qc-ZfA"/>
29+ <constraint firstItem="bdn-EE-6KU" firstAttribute="top" secondItem="6Tk-OE-BBY" secondAttribute="top" id="dww-F7-g9y"/>
30+ <constraint firstItem="6Tk-OE-BBY" firstAttribute="trailing" secondItem="bdn-EE-6KU" secondAttribute="trailing" id="wlT-ZO-QGd"/>
31+ <constraint firstItem="6Tk-OE-BBY" firstAttribute="bottom" secondItem="bdn-EE-6KU" secondAttribute="bottom" id="yXX-zW-vb8"/>
32+ </constraints>
33+ <viewLayoutGuide key="safeArea" id="6Tk-OE-BBY"/>
34+ </view>
35+ <navigationItem key="navigationItem" largeTitleDisplayMode="always" id="caN-kg-RZ4"/>
36+ <connections>
37+ <outlet property="tableView" destination="bdn-EE-6KU" id="O4Z-at-Hzw"/>
38+ </connections>
39+ </viewController>
40+ <placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
41+ </objects>
42+ <point key="canvasLocation" x="1076" y="132.68365817091455"/>
43+ </scene>
44+ <!--New Post View Controller-->
45+ <scene sceneID="TVK-xu-UdJ">
46+ <objects>
47+ <viewController storyboardIdentifier="NewPostViewController" id="uED-wX-77j" customClass="NewPostViewController" customModule="GDproject" customModuleProvider="target" sceneMemberID="viewController">
48+ <view key="view" contentMode="scaleToFill" id="6UN-Bs-PPg">
49+ <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
50+ <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
51+ <subviews>
52+ <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="sSz-uJ-A7n">
53+ <rect key="frame" x="0.0" y="20" width="375" height="647"/>
54+ <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
55+ </view>
56+ </subviews>
57+ <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
58+ <constraints>
59+ <constraint firstItem="sSz-uJ-A7n" firstAttribute="leading" secondItem="wxD-Ek-mgv" secondAttribute="leading" id="2J7-Bi-PzG"/>
60+ <constraint firstItem="wxD-Ek-mgv" firstAttribute="trailing" secondItem="sSz-uJ-A7n" secondAttribute="trailing" id="HrU-bs-qsE"/>
61+ <constraint firstItem="wxD-Ek-mgv" firstAttribute="bottom" secondItem="sSz-uJ-A7n" secondAttribute="bottom" id="oZ7-xQ-9Cb"/>
62+ <constraint firstItem="sSz-uJ-A7n" firstAttribute="top" secondItem="wxD-Ek-mgv" secondAttribute="top" id="zuN-mZ-hgU"/>
63+ </constraints>
64+ <viewLayoutGuide key="safeArea" id="wxD-Ek-mgv"/>
65+ </view>
66+ <connections>
67+ <outlet property="bottomTextViewConstraint" destination="oZ7-xQ-9Cb" id="6In-71-0TX"/>
68+ <outlet property="view1" destination="sSz-uJ-A7n" id="5nX-oT-kUi"/>
69+ </connections>
70+ </viewController>
71+ <placeholder placeholderIdentifier="IBFirstResponder" id="3fd-7N-vPg" userLabel="First Responder" sceneMemberID="firstResponder"/>
72+ </objects>
73+ <point key="canvasLocation" x="1773" y="132"/>
74+ </scene>
75+ <!--Full Post Controller-->
76+ <scene sceneID="nNH-1Q-jks">
77+ <objects>
78+ <tableViewController storyboardIdentifier="FullPostController" id="tcM-Fs-WJr" customClass="FullPostController" customModule="GDproject" customModuleProvider="target" sceneMemberID="viewController">
79+ <tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="grouped" separatorStyle="default" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="18" sectionFooterHeight="18" id="dmU-W2-lq6">
80+ <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
81+ <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
82+ <color key="backgroundColor" cocoaTouchSystemColor="groupTableViewBackgroundColor"/>
83+ <connections>
84+ <outlet property="dataSource" destination="tcM-Fs-WJr" id="Xvi-Mj-Id2"/>
85+ <outlet property="delegate" destination="tcM-Fs-WJr" id="190-Q0-2bn"/>
86+ </connections>
87+ </tableView>
88+ </tableViewController>
89+ <placeholder placeholderIdentifier="IBFirstResponder" id="CP8-RO-wn0" userLabel="First Responder" sceneMemberID="firstResponder"/>
90+ </objects>
91+ <point key="canvasLocation" x="2506" y="130"/>
92+ </scene>
93+ <!--Navigation Controller-->
94+ <scene sceneID="RSd-UJ-34B">
95+ <objects>
96+ <navigationController automaticallyAdjustsScrollViewInsets="NO" id="NuV-ZG-ld2" sceneMemberID="viewController">
97+ <toolbarItems/>
98+ <navigationBar key="navigationBar" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" largeTitles="YES" id="6qB-3A-tuL">
99+ <rect key="frame" x="0.0" y="20" width="375" height="96"/>
100+ <autoresizingMask key="autoresizingMask"/>
101+ </navigationBar>
102+ <nil name="viewControllers"/>
103+ <connections>
104+ <segue destination="BYZ-38-t0r" kind="relationship" relationship="rootViewController" id="ehh-1b-ZGK"/>
105+ </connections>
106+ </navigationController>
107+ <placeholder placeholderIdentifier="IBFirstResponder" id="POV-5T-jeQ" userLabel="First Responder" sceneMemberID="firstResponder"/>
108+ </objects>
109+ <point key="canvasLocation" x="150" y="133"/>
110+ </scene>
111+ </scenes>
112+</document>
GDproject/Constants.swiftnew file+14
@@ -0,0 +1,14 @@
1+//
2+// Constants.swift
3+// GDproject
4+//
5+// Created by cstore on 13/02/2019.
6+// Copyright © 2019 drHSE. All rights reserved.
7+//
8+
9+//constant for cell in posts NewsController.swift
10+let postCellId = "PostCell"
11+// constant for segmented controll in NewsController.swift and ChannelsController.swift
12+let headerNewsChannelsVC = "HeaderSegmentedControll"
13+// for transitioning to full post view
14+let fullPostControllerId = "FullPostController"
GDproject/Controller/ChannelsController.swiftnew file+15
@@ -0,0 +1,15 @@
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+
14+
15+}
GDproject/Controller/FullPostController.swiftnew file+133
@@ -0,0 +1,133 @@
1+//
2+// FullPostViewController.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 FullPostController: UITableViewController {
13+
14+ var post: Post?
15+
16+ override func viewDidLoad() {
17+ super.viewDidLoad()
18+
19+ tableView.register(PostViewCell.self, forCellReuseIdentifier: postCellId)
20+
21+ setUpNavigationBar()
22+ tableView.separatorStyle = .none
23+ }
24+
25+ func setUpNavigationBar(){
26+ navigationController?.navigationBar.prefersLargeTitles = false
27+ navigationItem.title = "\(post?.fromUser.login ?? "")"
28+ navigationItem.rightBarButtonItems = [UIBarButtonItem(barButtonSystemItem: .action, target: self, action: #selector(self.options))]
29+ }
30+
31+ @objc func options(){
32+ // drafts
33+ // saved
34+
35+ let optionMenu = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
36+ let editAction = UIAlertAction(title: "Send via message", style: .default)
37+ let shareAction = UIAlertAction(title: "Send via project", style: .default)
38+ let settingsAction = UIAlertAction(title: "Copy link", style: .default)
39+ let cancelAction = UIAlertAction(title: "Cancel", style: .cancel)
40+
41+ optionMenu.addAction(editAction)
42+ optionMenu.addAction(shareAction)
43+ optionMenu.addAction(settingsAction)
44+ optionMenu.addAction(cancelAction)
45+
46+ self.present(optionMenu, animated: true, completion: nil)
47+ }
48+ // MARK: - Table view data source
49+
50+ override func numberOfSections(in tableView: UITableView) -> Int {
51+ // #warning Incomplete implementation, return the number of sections
52+ return 2
53+ }
54+
55+
56+ override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView?
57+ {
58+ let mainView = UIView(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: 50))
59+
60+ let scrollView = UIScrollView()
61+
62+ scrollView.backgroundColor = .white
63+
64+ mainView.addSubview(scrollView)
65+ scrollView.edgesToSuperview()
66+
67+ scrollView.showsHorizontalScrollIndicator = false
68+
69+ var buttons: [UIButton] = []
70+ for hash in post!.hashtags {
71+ let button = UIButton()
72+ button.setTitle("#" + hash, for: .normal)
73+ button.backgroundColor = #colorLiteral(red: 0.8039215803, green: 0.8039215803, blue: 0.8039215803, alpha: 1)
74+ button.layer.cornerRadius = 10
75+ button.titleLabel?.font = UIFont.systemFont(ofSize: 14)
76+ button.setTitleColor(.black, for: .normal)
77+ buttons.append(button)
78+ }
79+
80+ let stackView = UIStackView(arrangedSubviews: buttons)
81+
82+ scrollView.addSubview(stackView)
83+
84+ stackView.axis = .horizontal
85+ stackView.alignment = .center
86+ stackView.spacing = 20
87+
88+ stackView.edgesToSuperview(insets: .left(20) + .top(10) + .right(20))
89+
90+ scrollView.contentSize = CGSize(width: 500, height: 50)
91+
92+ switch section {
93+ case 0:
94+ return mainView
95+ default:
96+ return nil
97+ }
98+ }
99+
100+
101+ override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
102+ switch section {
103+ case 0:
104+ return 50
105+ default:
106+ return 0
107+ }
108+ }
109+
110+ override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
111+ {
112+ switch section {
113+ case 0:
114+ return 1
115+ case 1:
116+ return post?.comments.count ?? 0
117+ default:
118+ return 0
119+ }
120+ }
121+
122+ override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
123+ {
124+ // TODO: make different cells for sections with switch
125+
126+ let cell = tableView.dequeueReusableCell(withIdentifier: postCellId) as! PostViewCell
127+
128+ cell.fill(with: post!.dataArray, true)
129+ cell.selectionStyle = .none
130+ return cell
131+ }
132+
133+}
GDproject/Controller/HeaderNewsChannels.swiftnew file+56
@@ -0,0 +1,56 @@
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+ weak var vc: NewsController?
16+
17+ let basicInfo = ChannelsController()
18+
19+ override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
20+ super.init(style: style, reuseIdentifier: reuseIdentifier)
21+ backgroundColor = .white
22+ setUpCell()
23+ }
24+
25+ required init?(coder aDecoder: NSCoder) {
26+ super.init(coder: aDecoder)
27+ }
28+
29+ func setUpCell(){
30+ addSubview(postsChannelsSegment)
31+ postsChannelsSegment.selectedSegmentIndex = 0
32+ postsChannelsSegment.addTarget(self, action: #selector(changedValue), for: .valueChanged)
33+ postsChannelsSegment.edgesToSuperview(insets: .left(16) + .right(16) + .top(8) + .bottom(8))
34+ }
35+
36+ // Initialize
37+ let postsChannelsSegment = UISegmentedControl(items: ["Posts", "Channels"])
38+
39+ @objc func changedValue(_ sender: UISegmentedControl) {
40+ let index = sender.selectedSegmentIndex
41+ switch index {
42+ case 0:
43+ print("posts")
44+ vc?.setUpNavigationItemsforPosts()
45+ case 1:
46+ print("channels")
47+ vc?.setUpNavigationItemsForChannels()
48+// self.tableView?.delegate = basicInfo
49+// self.tableView?.dataSource = basicInfo
50+// tableView?.reloadData()
51+ default:
52+ break
53+ }
54+ }
55+}
56+
GDproject/Controller/MyStackView.swiftnew file+27
@@ -0,0 +1,27 @@
1+//
2+// MyStackView.swift
3+// GDproject
4+//
5+// Created by cstore on 14/02/2019.
6+// Copyright © 2019 drHSE. All rights reserved.
7+//
8+
9+import UIKit
10+
11+class MyStackView: UIStackView {
12+
13+ var isFull: Bool = true
14+
15+
16+ override var bounds: CGRect {
17+ didSet{
18+ if frame.height == 300 && !isFull {
19+ let gradientLayer = CAGradientLayer()
20+ gradientLayer.colors = [UIColor(displayP3Red: 255, green: 255, blue: 255, alpha: 0).cgColor, UIColor.white.cgColor]
21+ gradientLayer.startPoint = CGPoint(x: 0.5, y: 0.5)
22+ gradientLayer.frame = self.bounds
23+ self.layer.addSublayer(gradientLayer)
24+ }
25+ }
26+ }
27+}
GDproject/Controller/NewPostViewController.swiftnew file+257
@@ -0,0 +1,257 @@
1+//
2+// NewPostViewController.swift
3+// GDproject
4+//
5+// Created by cstore on 05/02/2019.
6+// Copyright © 2019 drHSE. All rights reserved.
7+//
8+
9+import UIKit
10+import Cartography
11+import Marklight
12+import TinyConstraints
13+
14+class NewPostViewController: UIViewController, UITextViewDelegate {
15+
16+ @IBOutlet weak var view1: UIView!
17+ // Keep strong instance of the `NSTextStorage` subclass
18+ let textStorage = MarklightTextStorage()
19+
20+ weak var parentVC: NewsController?
21+
22+ static var draft: String = ""
23+ var textView: UITextView!
24+
25+ // buttons for attaching images
26+ var accessoryView: UIView = {
27+ let view = UIView()
28+ view.backgroundColor = .white
29+ return view
30+ }()
31+
32+ var addEquasion: UIButton = {
33+ var button = UIButton(type: .detailDisclosure)
34+ button.addTarget(self, action: #selector(addMathBrackets), for: .touchUpInside)
35+ return button
36+ }()
37+
38+ // stack view where buttons will be places
39+ var stackAccessoryView: UIStackView?
40+ // Connect the view1's bottom layout constraint to react to keyboard movements
41+
42+ @IBOutlet weak var bottomTextViewConstraint: NSLayoutConstraint!
43+
44+
45+ override func viewDidLoad()
46+ {
47+ super.viewDidLoad()
48+ setUpMD()
49+ setUpTextView()
50+ setUpAccessoryView()
51+ }
52+
53+ override func viewWillAppear(_ animated: Bool) {
54+ super.viewWillAppear(animated)
55+
56+ navigationController?.navigationBar.prefersLargeTitles = false
57+ navigationItem.title = "New post"
58+ textView.text = NewPostViewController.draft
59+ }
60+
61+ func setUpAccessoryView(){
62+ let views = [UIButton(type: .contactAdd),addEquasion]
63+ stackAccessoryView = UIStackView(arrangedSubviews: views)
64+
65+ stackAccessoryView?.alignment = .fill
66+ stackAccessoryView?.distribution = .equalSpacing
67+
68+ view1.addSubview(accessoryView)
69+ accessoryView.addSubview(stackAccessoryView!)
70+ accessoryView.height(40)
71+
72+ let separatorView = UIView()
73+ separatorView.backgroundColor = #colorLiteral(red: 0.8039215803, green: 0.8039215803, blue: 0.8039215803, alpha: 1)
74+ accessoryView.addSubview(separatorView)
75+ separatorView.height(1)
76+ separatorView.edgesToSuperview(excluding: .bottom)
77+
78+ accessoryView.edgesToSuperview(excluding: [.top])
79+ stackAccessoryView!.edgesToSuperview(insets: .left(16) + .right(16) + .top(1))
80+ }
81+
82+ func setUpTextView(){
83+ view.addConstraint(bottomTextViewConstraint)
84+ view1.addSubview(textView)
85+ textView.edgesToSuperview(insets: .top(8) + .left(8) + .bottom(40+8) + .right(8))
86+
87+ if #available(iOS 11.0, *) {
88+ textView.smartDashesType = .no
89+ textView.smartQuotesType = .no
90+ }
91+
92+ textView.isScrollEnabled = true
93+
94+ guard let bottomTextViewConstraint = bottomTextViewConstraint else { return }
95+ view.addConstraint(bottomTextViewConstraint)
96+
97+ // Add a beautiful padding to the `UITextView` content
98+ textView.textContainerInset = UIEdgeInsets(top: 4, left: 4, bottom: 4, right: 4)
99+ textView.delegate = self
100+ magicForKeyboardChanges()
101+ }
102+
103+
104+ func magicForKeyboardChanges()
105+ {
106+ /////////////////////////////
107+ // We do some magic to resize the `UITextView` to react the the keyboard size change (appearance, disappearance, ecc)
108+ NotificationCenter.default.addObserver(self, selector: #selector(handleKeyboardNotifications), name: UIResponder.keyboardWillShowNotification, object: nil)
109+
110+ NotificationCenter.default.addObserver(self, selector: #selector(handleKeyboardNotifications), name: UIResponder.keyboardWillHideNotification, object: nil)
111+
112+ // 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+ if self.textView.textStorage.string.hasSuffix("\n") {
115+ CATransaction.setCompletionBlock({ () -> Void in
116+ self.scrollToCaret(self.textView, animated: false)
117+ })
118+ } else {
119+ self.scrollToCaret(self.textView, animated: false)
120+ }
121+ }
122+
123+ }
124+
125+ @objc func handleKeyboardNotifications(notification: NSNotification){
126+ if let userInfo = notification.userInfo{
127+ // UIKeyboardFrameEndUserInfoKey
128+ let keyBoardFrame = (userInfo[UIResponder.keyboardFrameEndUserInfoKey] as! NSValue).cgRectValue
129+ bottomTextViewConstraint?.constant = notification.name == UIResponder.keyboardWillShowNotification ? keyBoardFrame.height : 0
130+ print(bottomTextViewConstraint!.constant)
131+
132+ UIView.animate(withDuration: 0, delay: 0, options: .curveEaseOut, animations: {
133+ self.view.layoutIfNeeded()
134+ }) { (completed) in
135+
136+ }
137+ }
138+ }
139+
140+ @objc func attachPhoto(){
141+
142+ }
143+
144+
145+ @objc func addMathBrackets()
146+ {
147+ if textView.text.count != 0 && textView.text.last != "\n" {
148+ textView.insertText("\n\\[\n ")
149+ }
150+ else {
151+ textView.insertText("\\[\n ")
152+ }
153+
154+ if let selectedRange = textView.selectedTextRange
155+ {
156+ textView.insertText("\n\\]\n")
157+
158+ if let newPosition = textView.position(from: selectedRange.start, offset: 0)
159+ {
160+ // set the new position
161+ textView.selectedTextRange = textView.textRange(from: newPosition, to: newPosition)
162+ }
163+ }
164+ }
165+
166+ func setUpMD(){
167+ textStorage.marklightTextProcessor.codeColor = UIColor.orange
168+ textStorage.marklightTextProcessor.quoteColor = UIColor.darkGray
169+ textStorage.marklightTextProcessor.syntaxColor = UIColor.blue
170+ textStorage.marklightTextProcessor.codeFontName = "Courier"
171+ textStorage.marklightTextProcessor.fontTextStyle = UIFont.TextStyle.subheadline.rawValue
172+ textStorage.marklightTextProcessor.hideSyntax = false
173+
174+ let layoutManager = NSLayoutManager()
175+
176+ // Assign the `UITextView`'s `NSLayoutManager` to the `NSTextStorage` subclass
177+ textStorage.addLayoutManager(layoutManager)
178+
179+ let textContainer = NSTextContainer()
180+ layoutManager.addTextContainer(textContainer)
181+
182+ textView = UITextView(frame: view.bounds, textContainer: textContainer)
183+ }
184+
185+ // MARK:- new post
186+ @objc func newPost(){
187+ let p = Post(dataArray: [.text(textView.text)], from: User(name: "Сева", id: 5, fullName: "Сева Леонидович"), date: "12.01.19")
188+
189+
190+ // adding row to uiTableView after adding new post
191+ guard let vc = parentVC else {return}
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()
198+ // somewhere here i will be sending server notifications about new post arrival
199+ }
200+
201+ @objc func actionSaveDraft(){
202+ let optionMenu = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
203+
204+ let saveAction = UIAlertAction(title: "Save draft", style: .default)
205+ {
206+ _ in
207+ NewPostViewController.draft = self.textView.text
208+ self.moveBackToParentVC()
209+ }
210+
211+ let deleteAction = UIAlertAction(title: "Delete draft", style: .destructive)
212+ {
213+ (_)
214+ in
215+ NewPostViewController.draft = ""
216+ self.moveBackToParentVC()
217+ }
218+
219+ let cancelAction = UIAlertAction(title: "Cancel", style: .cancel)
220+
221+ optionMenu.addAction(saveAction)
222+ optionMenu.addAction(deleteAction)
223+ optionMenu.addAction(cancelAction)
224+
225+ self.present(optionMenu, animated: true, completion: nil)
226+ }
227+
228+ @objc func closeView()
229+ {
230+ actionSaveDraft()
231+ }
232+
233+ func moveBackToParentVC(){
234+ let transition = CATransition()
235+ transition.duration = 0.5
236+ transition.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut)
237+ transition.type = CATransitionType.reveal
238+ transition.subtype = CATransitionSubtype.fromBottom
239+ navigationController?.view.layer.add(transition, forKey: nil)
240+ navigationController?.popViewController(animated: false)
241+ textView!.resignFirstResponder()
242+ }
243+
244+
245+
246+
247+ func textView(_ textView: UITextView, shouldInteractWith URL: URL, in characterRange: NSRange) -> Bool {
248+ print("Should interact with: \(URL)")
249+ return true
250+ }
251+
252+ func scrollToCaret(_ textView: UITextView, animated: Bool) {
253+ var rect = textView.caretRect(for: textView.selectedTextRange!.end)
254+ rect.size.height = rect.size.height + textView.textContainerInset.bottom
255+ textView.scrollRectToVisible(rect, animated: animated)
256+ }
257+}
GDproject/Controller/News/PostViewCell.swiftnew file+121
@@ -0,0 +1,121 @@
1+//
2+// PostViewCell.swift
3+// GDproject
4+//
5+// Created by cstore on 04/02/2019.
6+// Copyright © 2019 drHSE. All rights reserved.
7+//
8+
9+import UIKit
10+import Cartography
11+import MarkdownKit
12+import TinyConstraints
13+
14+class PostViewCell: UITableViewCell
15+{
16+ let nameLabel: UILabel = {
17+ let label = UILabel()
18+ label.textColor = #colorLiteral(red: 0, green: 0, blue: 0, alpha: 1)
19+ label.text = "vbogomazova"
20+ label.font = UIFont.boldSystemFont(ofSize: 16)
21+ return label
22+ }()
23+
24+ let fullNameLabel: UILabel = {
25+ let label = UILabel()
26+ label.textColor = #colorLiteral(red: 0.3333333433, green: 0.3333333433, blue: 0.3333333433, alpha: 1)
27+ label.text = "Богомазова Вероника Львовна"
28+ label.font = UIFont.systemFont(ofSize: 12)
29+ return label
30+ }()
31+
32+ let commentsLabel: UILabel = {
33+ let label = UILabel()
34+ label.font = UIFont.systemFont(ofSize: 12)
35+ label.textColor = #colorLiteral(red: 0.6000000238, green: 0.6000000238, blue: 0.6000000238, alpha: 1)
36+ return label
37+ }()
38+
39+ let shareButton: UIButton = {
40+ let button = UIButton(type: UIButton.ButtonType.detailDisclosure)
41+ return button
42+ }()
43+
44+ override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?)
45+ {
46+ super.init(style: style, reuseIdentifier: reuseIdentifier)
47+ }
48+
49+ required init?(coder aDecoder: NSCoder)
50+ {
51+ fatalError("init(coder:) has not been implemented")
52+ }
53+
54+ func createTextView(with text: String) -> UITextView
55+ {
56+ let markdownParser = MarkdownParser(font: UIFont.systemFont(ofSize: 16))
57+ let markdown = text
58+ markdownParser.enabledElements = .disabledAutomaticLink
59+ markdownParser.header.fontIncrease = 6
60+ markdownParser.code.textBackgroundColor = #colorLiteral(red: 0.8039215803, green: 0.8039215803, blue: 0.8039215803, alpha: 1)
61+
62+ let textView = UITextView()
63+ textView.isScrollEnabled = false
64+ textView.isEditable = false
65+ textView.isUserInteractionEnabled = false
66+ textView.attributedText = markdownParser.parse(markdown)
67+ return textView
68+ }
69+
70+ var views: [UIView] = []
71+ var data : [UIImage] = []
72+
73+ func fill(with info: [Media], _ isFullVersoin: Bool)
74+ {
75+ // important
76+ contentView.subviews.forEach({ $0.removeFromSuperview() })
77+
78+ data = []
79+ views = []
80+ for item in info.enumerated()
81+ {
82+ switch item.element
83+ {
84+ case .text(let text):
85+ views.append(createTextView(with: text))
86+ case .image(let images):
87+ self.data = images
88+ default:
89+ break
90+ }
91+ }
92+ setUpInStackView(isFullVersoin)
93+ }
94+
95+ func setUpInStackView(_ full : Bool){
96+ let nameStackView = UIStackView(arrangedSubviews: [nameLabel, fullNameLabel])
97+ nameStackView.axis = .vertical
98+ contentView.addSubview(nameStackView)
99+ //nameStackView.height(46)
100+ nameStackView.edgesToSuperview(excluding: .bottom, insets: .left(20) + .right(20) + .top(8))
101+
102+ let stackView = MyStackView(arrangedSubviews: views)
103+ stackView.isFull = full
104+ stackView.axis = .vertical
105+ contentView.addSubview(stackView)
106+ if !full {
107+ stackView.height(300, relation: .equalOrLess, isActive: true)
108+ }
109+ stackView.topToBottom(of: nameStackView, offset: 16, relation: .equal, isActive: true)
110+ stackView.edgesToSuperview(excluding: [.top, .bottom], insets: .left(16) + .right(16))
111+
112+ let commentsSharesStackView = UIStackView(arrangedSubviews: [ commentsLabel, shareButton])
113+ contentView.addSubview(commentsSharesStackView)
114+
115+ commentsLabel.text = "14.02.19 в 23:00"
116+ commentsSharesStackView.axis = .horizontal
117+ commentsSharesStackView.distribution = .equalSpacing
118+ commentsSharesStackView.edgesToSuperview(excluding: .top, insets: .bottom(10) + .left(16) + .right(16))
119+ stackView.bottomToTop(of: commentsSharesStackView)
120+ }
121+}
GDproject/Controller/NewsController.swiftnew file+204
@@ -0,0 +1,204 @@
1+//
2+// ViewController.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+// 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
14+class NewsController: UIViewController
15+{
16+
17+ @IBOutlet weak var tableView: UITableView!
18+
19+ var searchController = UISearchController(searchResultsController: nil)
20+
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")]
22+
23+ override func viewDidLoad()
24+ {
25+ super.viewDidLoad()
26+ tableView.register(HeaderNewsChannels.self, forCellReuseIdentifier: headerNewsChannelsVC)
27+ tableView.register(PostViewCell.self, forCellReuseIdentifier: postCellId)
28+
29+ tableView.delegate = self
30+ tableView.dataSource = self
31+ tableView.reloadData()
32+
33+ setUpNavigationItemsforPosts()
34+ searchController.searchBar.placeholder = "Search anything"
35+
36+ navigationItem.searchController = searchController
37+ definesPresentationContext = true
38+
39+ setUpBanner()
40+ }
41+
42+ override func viewWillAppear(_ animated: Bool) {
43+ super.viewWillAppear(animated)
44+ navigationController?.navigationBar.prefersLargeTitles = true
45+ }
46+
47+ func setUpNavigationItemsforPosts(){
48+ navigationItem.title = "Posts"
49+ navigationItem.rightBarButtonItems = [UIBarButtonItem(barButtonSystemItem: .compose, target: self, action: #selector(self.writePost(_:)))]
50+ }
51+
52+ func setUpNavigationItemsForChannels(){
53+ navigationItem.title = "Channels"
54+ navigationItem.rightBarButtonItems = [UIBarButtonItem(barButtonSystemItem: .add, target: self, action: #selector(addChannel))]
55+ }
56+
57+ @objc func writePost(_ barItem: UIBarButtonItem)
58+ {
59+ let vc = storyboard?.instantiateViewController(withIdentifier: "NewPostViewController") as! NewPostViewController
60+
61+ vc.navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Post", style: .plain, target: vc, action: #selector(vc.newPost))
62+ vc.navigationItem.leftBarButtonItem = UIBarButtonItem(title: "Close", style: .plain, target: vc, action: #selector(vc.closeView))
63+
64+ vc.parentVC = self
65+
66+ let transition = CATransition()
67+ transition.duration = 0.5
68+ transition.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut)
69+ transition.type = CATransitionType.moveIn
70+ transition.subtype = CATransitionSubtype.fromTop
71+ navigationController?.view.layer.add(transition, forKey: nil)
72+ navigationController?.pushViewController(vc, animated: false)
73+ }
74+
75+ @objc func addChannel(){
76+ print("Add channel")
77+ }
78+
79+ // for animating the banner
80+ var topConstraint: NSLayoutConstraint?
81+
82+ let bannerView: UIView = {
83+ let view = UIView()
84+ view.backgroundColor = .blue
85+ view.layer.cornerRadius = 25.0
86+ view.clipsToBounds = true
87+ return view
88+ }()
89+
90+ let statusLabel: UILabel = {
91+ let label = UILabel()
92+ label.text = "-"
93+ label.textColor = .white
94+ label.textAlignment = .center
95+ return label
96+ }()
97+
98+ private func setUpBanner()
99+ {
100+ view.addSubview(bannerView)
101+ bannerView.addSubview(statusLabel)
102+ statusLabel.edgesToSuperview()
103+
104+ let tap = UITapGestureRecognizer(target: self, action: #selector(handleTap(sender:)))
105+
106+ bannerView.addGestureRecognizer(tap)
107+ topConstraint = NSLayoutConstraint(item: bannerView, attribute: .top, relatedBy: .equal, toItem: view.safeAreaLayoutGuide, attribute: .top, multiplier: 1, constant: -300)
108+ view.addConstraint(topConstraint!)
109+
110+ bannerView.edgesToSuperview(excluding: [.bottom, .top, .left], insets: .right(20), usingSafeArea: true)
111+ bannerView.height(50)
112+ bannerView.width(50)
113+ }
114+
115+ // when table is scrolling no deletion is availiable
116+ @objc func handleTap(sender: UITapGestureRecognizer? = nil) {
117+ let indexPath = IndexPath(row: 0, section: 0)
118+ self.tableView.scrollToRow(at: indexPath, at: .top, animated: true)
119+// isBannerVisible = false
120+// changeConstraint(isVisible: false)
121+ }
122+
123+ // animation for banner
124+ func changeConstraint(isVisible: Bool){
125+ topConstraint?.constant = isVisible ? 50 : -300
126+
127+ UIView.animate(withDuration: 0.5, delay: 0, options: .curveEaseOut, animations: {
128+ self.view.layoutIfNeeded()
129+ }) { (completed) in
130+
131+ }
132+ }
133+
134+ var isBannerVisible: Bool = false
135+
136+ func scrollViewDidScroll(_ scrollView: UIScrollView) {
137+ print(scrollView.contentOffset.y)
138+ if scrollView.contentOffset.y >= 50 && !isBannerVisible{
139+ isBannerVisible = true
140+ changeConstraint(isVisible: true)
141+ }
142+
143+ if isBannerVisible && scrollView.contentOffset.y == 0{
144+ isBannerVisible = false
145+ changeConstraint(isVisible: false)
146+ }
147+ }
148+}
149+
150+// MARK:- tableView delegate
151+extension NewsController: UITableViewDelegate{
152+ func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
153+ {
154+ tableView.deselectRow(at: indexPath, animated: true)
155+
156+ let vc = storyboard!.instantiateViewController(withIdentifier: fullPostControllerId) as! FullPostController
157+
158+ vc.post = dataSourse[indexPath.row]
159+ navigationController!.pushViewController(vc, animated: true)
160+ }
161+}
162+
163+// MARK:- tableView dataSourse
164+extension NewsController: UITableViewDataSource
165+{
166+ func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
167+ return dataSourse.count
168+ }
169+
170+ func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
171+ {
172+ let cell = tableView.dequeueReusableCell(withIdentifier: postCellId, for: indexPath) as! PostViewCell
173+
174+ cell.fill(with: dataSourse[indexPath.row].dataArray, false)
175+ cell.selectionStyle = .none
176+ return cell
177+ }
178+
179+ func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
180+ return UITableView.automaticDimension
181+ }
182+
183+ func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
184+ return 100.0
185+ }
186+
187+ func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
188+ return 46.0
189+ }
190+
191+ func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView?
192+ {
193+ let cell = tableView.dequeueReusableCell(withIdentifier: headerNewsChannelsVC) as! HeaderNewsChannels
194+ cell.vc = self
195+
196+ let view = UIView(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: 46.0))
197+ view.addSubview(cell)
198+ cell.edgesToSuperview()
199+
200+ return view
201+ }
202+
203+
204+}
GDproject/Info.plistnew file+45
@@ -0,0 +1,45 @@
1+<?xml version="1.0" encoding="UTF-8"?>
2+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3+<plist version="1.0">
4+<dict>
5+ <key>CFBundleDevelopmentRegion</key>
6+ <string>$(DEVELOPMENT_LANGUAGE)</string>
7+ <key>CFBundleExecutable</key>
8+ <string>$(EXECUTABLE_NAME)</string>
9+ <key>CFBundleIdentifier</key>
10+ <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
11+ <key>CFBundleInfoDictionaryVersion</key>
12+ <string>6.0</string>
13+ <key>CFBundleName</key>
14+ <string>$(PRODUCT_NAME)</string>
15+ <key>CFBundlePackageType</key>
16+ <string>APPL</string>
17+ <key>CFBundleShortVersionString</key>
18+ <string>1.0</string>
19+ <key>CFBundleVersion</key>
20+ <string>1</string>
21+ <key>LSRequiresIPhoneOS</key>
22+ <true/>
23+ <key>UILaunchStoryboardName</key>
24+ <string>LaunchScreen</string>
25+ <key>UIMainStoryboardFile</key>
26+ <string>Main</string>
27+ <key>UIRequiredDeviceCapabilities</key>
28+ <array>
29+ <string>armv7</string>
30+ </array>
31+ <key>UISupportedInterfaceOrientations</key>
32+ <array>
33+ <string>UIInterfaceOrientationPortrait</string>
34+ <string>UIInterfaceOrientationLandscapeLeft</string>
35+ <string>UIInterfaceOrientationLandscapeRight</string>
36+ </array>
37+ <key>UISupportedInterfaceOrientations~ipad</key>
38+ <array>
39+ <string>UIInterfaceOrientationPortrait</string>
40+ <string>UIInterfaceOrientationPortraitUpsideDown</string>
41+ <string>UIInterfaceOrientationLandscapeLeft</string>
42+ <string>UIInterfaceOrientationLandscapeRight</string>
43+ </array>
44+</dict>
45+</plist>
GDproject/Simple model/Post.swiftnew file+39
@@ -0,0 +1,39 @@
1+//
2+// Post.swift
3+// NewsFeed
4+//
5+// Created by cstore on 12/01/2019.
6+// Copyright © 2019 drHSE. All rights reserved.
7+//
8+
9+import Foundation
10+import UIKit
11+
12+struct Post {
13+ var dataArray: [Media]
14+ var fromUser: User
15+ var atDate: String
16+ var comments: [Comment]
17+ var hashtags: [String] = ["ФКН", "Подбельский", "НИУВШЭ", "Шершаков", "ПАД", "Интересное","Мемы","Забавное","Учеба","Наука"]
18+
19+ init(dataArray: [Media], from: User, date: String, comments: [Comment] = [])
20+ {
21+ self.dataArray = dataArray
22+ fromUser = from
23+ atDate = date
24+ self.comments = comments
25+ }
26+}
27+
28+
29+enum Media{
30+ case text(String)
31+ case image([UIImage])
32+ case quote
33+}
34+
35+struct Comment {
36+ var from: User
37+ var atTime: String
38+ var withData: String
39+}
GDproject/Simple model/User.swiftnew file+40
@@ -0,0 +1,40 @@
1+//
2+// User.swift
3+// NewsFeed
4+//
5+// Created by cstore on 12/01/2019.
6+// Copyright © 2019 drHSE. All rights reserved.
7+//
8+
9+import Foundation
10+import UIKit
11+
12+struct User {
13+ //var photo: UIImage? = #imageLiteral(resourceName: "image")
14+ var login: String
15+ var id: Int
16+ var surname: String?
17+ var fullName: String
18+ var initials: (surname: String, name: String, optional: String?)?
19+ var placeOfWork: String?
20+ var faculty: String?
21+
22+ init(name: String, id: Int, fullName: String) {
23+ self.login = name
24+ self.id = id
25+ self.fullName = fullName
26+ }
27+
28+ init(surname: String, name: String, optional: String?, emailName: String, id: Int, place: String?, faculty: String?)
29+ {
30+ self.id = id
31+ self.login = emailName
32+ self.initials = (surname, name, optional)
33+
34+ self.fullName = "\(surname) \(name) \(optional ?? "")"
35+ self.placeOfWork = place
36+ if let f = faculty {
37+ self.faculty = f
38+ }
39+ }
40+}
GDproject/Supporting files/AppDelegate.swiftnew file+46
@@ -0,0 +1,46 @@
1+//
2+// AppDelegate.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+@UIApplicationMain
12+class AppDelegate: UIResponder, UIApplicationDelegate {
13+
14+ var window: UIWindow?
15+
16+
17+ func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
18+ // Override point for customization after application launch.
19+ return true
20+ }
21+
22+ func applicationWillResignActive(_ application: UIApplication) {
23+ // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
24+ // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
25+ }
26+
27+ func applicationDidEnterBackground(_ application: UIApplication) {
28+ // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
29+ // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
30+ }
31+
32+ func applicationWillEnterForeground(_ application: UIApplication) {
33+ // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
34+ }
35+
36+ func applicationDidBecomeActive(_ application: UIApplication) {
37+ // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
38+ }
39+
40+ func applicationWillTerminate(_ application: UIApplication) {
41+ // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
42+ }
43+
44+
45+}
46+
GDproject/Supporting files/Assets.xcassets/AppIcon.appiconset/Contents.jsonnew file+98
@@ -0,0 +1,98 @@
1+{
2+ "images" : [
3+ {
4+ "idiom" : "iphone",
5+ "size" : "20x20",
6+ "scale" : "2x"
7+ },
8+ {
9+ "idiom" : "iphone",
10+ "size" : "20x20",
11+ "scale" : "3x"
12+ },
13+ {
14+ "idiom" : "iphone",
15+ "size" : "29x29",
16+ "scale" : "2x"
17+ },
18+ {
19+ "idiom" : "iphone",
20+ "size" : "29x29",
21+ "scale" : "3x"
22+ },
23+ {
24+ "idiom" : "iphone",
25+ "size" : "40x40",
26+ "scale" : "2x"
27+ },
28+ {
29+ "idiom" : "iphone",
30+ "size" : "40x40",
31+ "scale" : "3x"
32+ },
33+ {
34+ "idiom" : "iphone",
35+ "size" : "60x60",
36+ "scale" : "2x"
37+ },
38+ {
39+ "idiom" : "iphone",
40+ "size" : "60x60",
41+ "scale" : "3x"
42+ },
43+ {
44+ "idiom" : "ipad",
45+ "size" : "20x20",
46+ "scale" : "1x"
47+ },
48+ {
49+ "idiom" : "ipad",
50+ "size" : "20x20",
51+ "scale" : "2x"
52+ },
53+ {
54+ "idiom" : "ipad",
55+ "size" : "29x29",
56+ "scale" : "1x"
57+ },
58+ {
59+ "idiom" : "ipad",
60+ "size" : "29x29",
61+ "scale" : "2x"
62+ },
63+ {
64+ "idiom" : "ipad",
65+ "size" : "40x40",
66+ "scale" : "1x"
67+ },
68+ {
69+ "idiom" : "ipad",
70+ "size" : "40x40",
71+ "scale" : "2x"
72+ },
73+ {
74+ "idiom" : "ipad",
75+ "size" : "76x76",
76+ "scale" : "1x"
77+ },
78+ {
79+ "idiom" : "ipad",
80+ "size" : "76x76",
81+ "scale" : "2x"
82+ },
83+ {
84+ "idiom" : "ipad",
85+ "size" : "83.5x83.5",
86+ "scale" : "2x"
87+ },
88+ {
89+ "idiom" : "ios-marketing",
90+ "size" : "1024x1024",
91+ "scale" : "1x"
92+ }
93+ ],
94+ "info" : {
95+ "version" : 1,
96+ "author" : "xcode"
97+ }
98+}
GDproject/Supporting files/Assets.xcassets/Contents.jsonnew file+6
@@ -0,0 +1,6 @@
1+{
2+ "info" : {
3+ "version" : 1,
4+ "author" : "xcode"
5+ }
6+}
GDproject/Supporting files/Assets.xcassets/icons8-share-3-500.imageset/Contents.jsonnew file+21
@@ -0,0 +1,21 @@
1+{
2+ "images" : [
3+ {
4+ "idiom" : "universal",
5+ "filename" : "icons8-share-3-500.png",
6+ "scale" : "1x"
7+ },
8+ {
9+ "idiom" : "universal",
10+ "scale" : "2x"
11+ },
12+ {
13+ "idiom" : "universal",
14+ "scale" : "3x"
15+ }
16+ ],
17+ "info" : {
18+ "version" : 1,
19+ "author" : "xcode"
20+ }
21+}
GDproject/Supporting files/Assets.xcassets/icons8-share-3-500.imageset/icons8-share-3-500.pngnew file

Binary file not shown.

GDproject/Supporting files/Base.lproj/LaunchScreen.storyboardnew file+25
@@ -0,0 +1,25 @@
1+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
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">
3+ <dependencies>
4+ <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13104.12"/>
5+ <capability name="Safe area layout guides" minToolsVersion="9.0"/>
6+ <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
7+ </dependencies>
8+ <scenes>
9+ <!--View Controller-->
10+ <scene sceneID="EHf-IW-A2E">
11+ <objects>
12+ <viewController id="01J-lp-oVM" sceneMemberID="viewController">
13+ <view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
14+ <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
15+ <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
16+ <color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
17+ <viewLayoutGuide key="safeArea" id="6Tk-OE-BBY"/>
18+ </view>
19+ </viewController>
20+ <placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
21+ </objects>
22+ <point key="canvasLocation" x="53" y="375"/>
23+ </scene>
24+ </scenes>
25+</document>