git.iko.soy/dashared/GDproject
on master help sign in
Merge branch 'master' into developer
3a24fe0Darya Rednikina
GDproject.xcodeproj/project.pbxproj+1
@@ -289,6 +289,7 @@
289 12DB7FD722181CD20096878E /* BasicInfoController.swift in Sources */,
289 12DB7FD722181CD20096878E /* BasicInfoController.swift in Sources */,
290 12E36DCE22144756006FCDD7 /* Constants.swift in Sources */,
290 12E36DCE22144756006FCDD7 /* Constants.swift in Sources */,
291 12DB7FDD221872F80096878E /* SettingsViewController.swift in Sources */,
291 12DB7FDD221872F80096878E /* SettingsViewController.swift in Sources */,
292+
292 );
293 );
293 runOnlyForDeploymentPostprocessing = 0;
294 runOnlyForDeploymentPostprocessing = 0;
294 };
295 };
GDproject/Constants.swift+1
@@ -18,3 +18,4 @@ let basicInfoCellId = "BasicInfoCell"
18let infoCellId = "InfoCell"
18let infoCellId = "InfoCell"
19
19
20let inviteVC = "InviteViewController"
20let 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
152 if !full {
152 if !full {
153 stackView.height(300, relation: .equalOrLess, isActive: true)
153 stackView.height(300, relation: .equalOrLess, isActive: true)
154 }
154 }
155+
155 stackView.topToBottom(of: mainView, offset: 0, relation: .equal, isActive: true)
156 stackView.topToBottom(of: mainView, offset: 0, relation: .equal, isActive: true)
157+
156 stackView.edgesToSuperview(excluding: [.top, .bottom], insets: .left(16) + .right(16))
158 stackView.edgesToSuperview(excluding: [.top, .bottom], insets: .left(16) + .right(16))
157
159
158 let commentsSharesStackView = UIStackView(arrangedSubviews: [ commentsLabel, shareButton])
160 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 {
14 var fromUser: User
14 var fromUser: User
15 var atDate: String
15 var atDate: String
16 var comments: [Comment] = []
16 var comments: [Comment] = []
17+
17 var hashtags: [String] = ["ФКН", "Подбельский", "НИУВШЭ", "Шершаков", "ПАД", "Интересное","Мемы","Забавное","Учеба","Наука"]
18 var hashtags: [String] = ["ФКН", "Подбельский", "НИУВШЭ", "Шершаков", "ПАД", "Интересное","Мемы","Забавное","Учеба","Наука"]
18
19
19 init(dataArray: [Media], from: User, date: String, comments: [Comment] = [])
20 init(dataArray: [Media], from: User, date: String, comments: [Comment] = [])
@@ -29,6 +30,7 @@ struct Post {
29 fromUser = User(name: "vbogomazova", id: 2, fullName: "Богомазова Вероника Львовна")
30 fromUser = User(name: "vbogomazova", id: 2, fullName: "Богомазова Вероника Львовна")
30 atDate = "23.03.19 в 23:33"
31 atDate = "23.03.19 в 23:33"
31 }
32 }
33+
32}
34}
33
35
34
36
GDproject/Simple model/User.swift+1
@@ -18,6 +18,7 @@ struct User {
18 var placeOfWork: String?
18 var placeOfWork: String?
19 var faculty: String?
19 var faculty: String?
20 let posts: [Post] = []
20 let posts: [Post] = []
21+
21
22
22 init(name: String, id: Int, fullName: String) {
23 init(name: String, id: Int, fullName: String) {
23 self.login = name
24 self.login = name