git.iko.soy/dashared/GDproject
on master help sign in
Merge branch 'master' into developer
commit3a24fe05d7e694e110e7b7ecbafa630858aba864 authorDarya Rednikina <31587869+dashared@users.noreply.github.com> dateSun 17 Feb 2019, 13:46 (8 years ago) parentdf5de7c3c5c062
11 files changed+699
GDproject.xcodeproj/project.pbxproj+1 GDproject/Constants.swift+1 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+2 GDproject/Controller/NewsController.swift+204 GDproject/Simple model/Post.swift+2 GDproject/Simple model/User.swift+1
GDproject.xcodeproj/project.pbxproj+1
@@ -289,6 +289,7 @@
289289 12DB7FD722181CD20096878E /* BasicInfoController.swift in Sources */,
290290 12E36DCE22144756006FCDD7 /* Constants.swift in Sources */,
291291 12DB7FDD221872F80096878E /* SettingsViewController.swift in Sources */,
292+
292293 );
293294 runOnlyForDeploymentPostprocessing = 0;
294295 };
GDproject/Constants.swift+1
@@ -18,3 +18,4 @@ let basicInfoCellId = "BasicInfoCell"
1818let infoCellId = "InfoCell"
1919
2020let inviteVC = "InviteViewController"
21+
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.swift+2
@@ -152,7 +152,9 @@ class PostViewCell: UITableViewCell
152152 if !full {
153153 stackView.height(300, relation: .equalOrLess, isActive: true)
154154 }
155+
155156 stackView.topToBottom(of: mainView, offset: 0, relation: .equal, isActive: true)
157+
156158 stackView.edgesToSuperview(excluding: [.top, .bottom], insets: .left(16) + .right(16))
157159
158160 let commentsSharesStackView = UIStackView(arrangedSubviews: [ commentsLabel, shareButton])
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/Simple model/Post.swift+2
@@ -14,6 +14,7 @@ struct Post {
1414 var fromUser: User
1515 var atDate: String
1616 var comments: [Comment] = []
17+
1718 var hashtags: [String] = ["ФКН", "Подбельский", "НИУВШЭ", "Шершаков", "ПАД", "Интересное","Мемы","Забавное","Учеба","Наука"]
1819
1920 init(dataArray: [Media], from: User, date: String, comments: [Comment] = [])
@@ -29,6 +30,7 @@ struct Post {
2930 fromUser = User(name: "vbogomazova", id: 2, fullName: "Богомазова Вероника Львовна")
3031 atDate = "23.03.19 в 23:33"
3132 }
33+
3234}
3335
3436
GDproject/Simple model/User.swift+1
@@ -18,6 +18,7 @@ struct User {
1818 var placeOfWork: String?
1919 var faculty: String?
2020 let posts: [Post] = []
21+
2122
2223 init(name: String, id: Int, fullName: String) {
2324 self.login = name