Showing
40 changed files
with
610 additions
and
486 deletions
No preview for this file type
... | ... | @@ -3,86 +3,4 @@ |
3 | 3 | uuid = "7D2BF3CE-0152-4175-98D9-E41B0FA9C333" |
4 | 4 | type = "1" |
5 | 5 | version = "2.0"> |
6 | - <Breakpoints> | |
7 | - <BreakpointProxy | |
8 | - BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint"> | |
9 | - <BreakpointContent | |
10 | - uuid = "F889FE98-5ADA-45D9-9094-5319F398E5D0" | |
11 | - shouldBeEnabled = "Yes" | |
12 | - ignoreCount = "0" | |
13 | - continueAfterRunningActions = "No" | |
14 | - filePath = "browser/Models/HistoryToolbarMenuCases.swift" | |
15 | - startingColumnNumber = "9223372036854775807" | |
16 | - endingColumnNumber = "9223372036854775807" | |
17 | - startingLineNumber = "21" | |
18 | - endingLineNumber = "21" | |
19 | - landmarkName = "action" | |
20 | - landmarkType = "24"> | |
21 | - </BreakpointContent> | |
22 | - </BreakpointProxy> | |
23 | - <BreakpointProxy | |
24 | - BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint"> | |
25 | - <BreakpointContent | |
26 | - uuid = "AF29D2F2-0DE8-426B-B8C0-6E69F97CA3CA" | |
27 | - shouldBeEnabled = "No" | |
28 | - ignoreCount = "0" | |
29 | - continueAfterRunningActions = "No" | |
30 | - filePath = "browser/Modules/RemoveAdvert/Controller/RemoveAdvertViewController.swift" | |
31 | - startingColumnNumber = "9223372036854775807" | |
32 | - endingColumnNumber = "9223372036854775807" | |
33 | - startingLineNumber = "82" | |
34 | - endingLineNumber = "82" | |
35 | - landmarkName = "shieldButtonTapped(_:)" | |
36 | - landmarkType = "7"> | |
37 | - </BreakpointContent> | |
38 | - </BreakpointProxy> | |
39 | - <BreakpointProxy | |
40 | - BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint"> | |
41 | - <BreakpointContent | |
42 | - uuid = "2F610807-91FB-4B53-BAE6-77E3D9664161" | |
43 | - shouldBeEnabled = "No" | |
44 | - ignoreCount = "0" | |
45 | - continueAfterRunningActions = "No" | |
46 | - filePath = "browser/Modules/RemoveAdvert/Controller/RemoveAdvertViewController.swift" | |
47 | - startingColumnNumber = "9223372036854775807" | |
48 | - endingColumnNumber = "9223372036854775807" | |
49 | - startingLineNumber = "86" | |
50 | - endingLineNumber = "86" | |
51 | - landmarkName = "shieldButtonTapped(_:)" | |
52 | - landmarkType = "7"> | |
53 | - </BreakpointContent> | |
54 | - </BreakpointProxy> | |
55 | - <BreakpointProxy | |
56 | - BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint"> | |
57 | - <BreakpointContent | |
58 | - uuid = "3D9602FE-229B-4486-9E84-86F3385737CB" | |
59 | - shouldBeEnabled = "No" | |
60 | - ignoreCount = "0" | |
61 | - continueAfterRunningActions = "No" | |
62 | - filePath = "browser/Modules/Home/Controller/BrowserHomeViewController.swift" | |
63 | - startingColumnNumber = "9223372036854775807" | |
64 | - endingColumnNumber = "9223372036854775807" | |
65 | - startingLineNumber = "236" | |
66 | - endingLineNumber = "236" | |
67 | - landmarkName = "tabsButtonHandler()" | |
68 | - landmarkType = "7"> | |
69 | - </BreakpointContent> | |
70 | - </BreakpointProxy> | |
71 | - <BreakpointProxy | |
72 | - BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint"> | |
73 | - <BreakpointContent | |
74 | - uuid = "890732EB-28CC-4180-BED8-D29D0A5F9C6A" | |
75 | - shouldBeEnabled = "No" | |
76 | - ignoreCount = "0" | |
77 | - continueAfterRunningActions = "No" | |
78 | - filePath = "browser/Modules/Home/Controller/BrowserHomeViewController.swift" | |
79 | - startingColumnNumber = "9223372036854775807" | |
80 | - endingColumnNumber = "9223372036854775807" | |
81 | - startingLineNumber = "235" | |
82 | - endingLineNumber = "235" | |
83 | - landmarkName = "tabsButtonHandler()" | |
84 | - landmarkType = "7"> | |
85 | - </BreakpointContent> | |
86 | - </BreakpointProxy> | |
87 | - </Breakpoints> | |
88 | 6 | </Bucket> | ... | ... |
... | ... | @@ -13,29 +13,31 @@ enum menuCases: CaseIterable { |
13 | 13 | case todayAndYesterday |
14 | 14 | case today |
15 | 15 | case lastHour |
16 | - //MARK: todo | |
17 | 16 | var action: UIAction { |
18 | 17 | switch self { |
19 | 18 | case .allTime: |
20 | 19 | return UIAction(title: "All time") { _ in |
21 | 20 | HistoryDBManager.shared.cleanHistory() |
22 | - | |
23 | 21 | } |
22 | + | |
24 | 23 | case .lastMonth: |
25 | 24 | return UIAction(title: "The last 30 days") { _ in |
26 | 25 | let lastMonth = Calendar.current.date(byAdding: .day, value: -30, to: Date()) ?? Date() |
27 | 26 | HistoryDBManager.shared.deleteHistoryInRange(startDate: lastMonth) |
28 | 27 | } |
28 | + | |
29 | 29 | case .todayAndYesterday: |
30 | 30 | return UIAction(title: "Today and yesterday") { _ in |
31 | 31 | let yesterday = Calendar.current.date(byAdding: .day, value: -1, to: Date()) ?? Date() |
32 | 32 | HistoryDBManager.shared.deleteHistoryInRange(startDate: yesterday) |
33 | 33 | } |
34 | + | |
34 | 35 | case .today: |
35 | 36 | return UIAction(title: "Today") { _ in |
36 | 37 | let startOfToday = Calendar.current.startOfDay(for: Date()) |
37 | 38 | HistoryDBManager.shared.deleteHistoryInRange(startDate: startOfToday) |
38 | 39 | } |
40 | + | |
39 | 41 | case .lastHour: |
40 | 42 | return UIAction(title: "The last hour") { _ in |
41 | 43 | let lastHour = Calendar.current.date(byAdding: .hour, value: -1, to: Date()) ?? Date() | ... | ... |
... | ... | @@ -4,13 +4,12 @@ |
4 | 4 | // |
5 | 5 | // Created by Artem Talko on 29.09.2023. |
6 | 6 | // |
7 | - | |
7 | +//MARK: Checked | |
8 | 8 | import UIKit |
9 | 9 | import RealmSwift |
10 | 10 | |
11 | 11 | final class HistoryViewController: UIViewController { |
12 | 12 | private let mainView = HistoryView() |
13 | - | |
14 | 13 | private var objectNotificationToken: NotificationToken? |
15 | 14 | |
16 | 15 | private var historyData: [HistoryElement] = [] { |
... | ... | @@ -18,6 +17,7 @@ final class HistoryViewController: UIViewController { |
18 | 17 | filteredData = historyData |
19 | 18 | } |
20 | 19 | } |
20 | + | |
21 | 21 | private var filteredData: [HistoryElement] = [] { |
22 | 22 | didSet { |
23 | 23 | mainView.historyTabsTableView.reloadData() |
... | ... | @@ -26,12 +26,14 @@ final class HistoryViewController: UIViewController { |
26 | 26 | |
27 | 27 | override func viewWillAppear(_ animated: Bool) { |
28 | 28 | super.viewWillAppear(animated) |
29 | + | |
29 | 30 | navigationController?.isNavigationBarHidden = false |
30 | 31 | navigationItem.title = "History" |
31 | 32 | } |
32 | 33 | |
33 | 34 | override func viewDidLoad() { |
34 | 35 | super.viewDidLoad() |
36 | + | |
35 | 37 | initViewController() |
36 | 38 | } |
37 | 39 | |
... | ... | @@ -39,20 +41,21 @@ final class HistoryViewController: UIViewController { |
39 | 41 | setupTableView() |
40 | 42 | addTargets() |
41 | 43 | setupSearchBar() |
42 | - historyData = HistoryDBManager.shared.getHistoryDataForTableView() | |
43 | 44 | historyChangesObserve() |
44 | 45 | } |
45 | 46 | |
46 | 47 | override func loadView() { |
47 | 48 | view = mainView |
48 | 49 | view.backgroundColor = .white |
50 | + | |
49 | 51 | navigationController?.isNavigationBarHidden = false |
50 | 52 | navigationItem.title = "History" |
51 | - // historyChangesObserve() | |
52 | 53 | } |
53 | 54 | |
54 | 55 | init() { |
55 | 56 | super.init(nibName: nil, bundle: nil) |
57 | + | |
58 | + historyData = HistoryDBManager.shared.getHistoryDataForTableView() | |
56 | 59 | } |
57 | 60 | |
58 | 61 | required init?(coder: NSCoder) { |
... | ... | @@ -76,8 +79,8 @@ extension HistoryViewController: UITableViewDelegate, UITableViewDataSource { |
76 | 79 | } |
77 | 80 | |
78 | 81 | func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { |
79 | - guard let cell = tableView.dequeueReusableCell(withIdentifier: "HistoryTableViewCell", for: indexPath) as? HistoryTableViewCell else { | |
80 | - return HistoryTableViewCell() | |
82 | + guard let cell = tableView.dequeueReusableCell(withIdentifier: HistoryTableViewCell.tabID, for: indexPath) as? HistoryTableViewCell else { | |
83 | + return UITableViewCell() | |
81 | 84 | } |
82 | 85 | let row = indexPath.row |
83 | 86 | let section = indexPath.section |
... | ... | @@ -97,6 +100,7 @@ extension HistoryViewController: UITableViewDelegate, UITableViewDataSource { |
97 | 100 | let section = indexPath.section |
98 | 101 | let historyCellData = filteredData[section].stories[row] |
99 | 102 | let tabId = historyCellData.historyCellId |
103 | + | |
100 | 104 | HistoryDBManager.shared.deleteHistoryCell(tabId: tabId) |
101 | 105 | filteredData[section].stories.remove(at: row) |
102 | 106 | mainView.historyTabsTableView.reloadData() |
... | ... | @@ -107,6 +111,7 @@ extension HistoryViewController: UITableViewDelegate, UITableViewDataSource { |
107 | 111 | let section = indexPath.section |
108 | 112 | let index = indexPath.row |
109 | 113 | let urlForFunc = historyData[section].stories[index].siteUrl |
114 | + | |
110 | 115 | if let navigationController = presentingViewController as? NavigationViewController { |
111 | 116 | for viewController in navigationController.viewControllers { |
112 | 117 | if let browserHomeViewController = viewController as? BrowserHomeViewController { |
... | ... | @@ -116,16 +121,9 @@ extension HistoryViewController: UITableViewDelegate, UITableViewDataSource { |
116 | 121 | dismiss(animated: true) |
117 | 122 | } |
118 | 123 | } |
119 | - | |
120 | - func setupTableView() { | |
121 | - mainView.historyTabsTableView.dataSource = self | |
122 | - mainView.historyTabsTableView.delegate = self | |
123 | - mainView.historyTabsTableView.register(HistoryTableViewCell.self, forCellReuseIdentifier: StringConstants.historyTableViewCell) | |
124 | - } | |
125 | 124 | } |
126 | 125 | |
127 | 126 | |
128 | - | |
129 | 127 | //MARK: Helper |
130 | 128 | extension HistoryViewController { |
131 | 129 | private func addTargets() { |
... | ... | @@ -136,12 +134,18 @@ extension HistoryViewController { |
136 | 134 | private func addToolbarTargets() { |
137 | 135 | mainView.historyToolbarView.action = didTabButtonTapped |
138 | 136 | } |
137 | + | |
138 | + private func setupTableView() { | |
139 | + mainView.historyTabsTableView.dataSource = self | |
140 | + mainView.historyTabsTableView.delegate = self | |
141 | + mainView.historyTabsTableView.register(HistoryTableViewCell.self, forCellReuseIdentifier: HistoryTableViewCell.tabID) | |
142 | + } | |
139 | 143 | } |
140 | 144 | |
141 | 145 | |
142 | 146 | //MARK: Targets |
143 | 147 | extension HistoryViewController { |
144 | - func didTabButtonTapped(type: historyToolbarElementType) { | |
148 | + private func didTabButtonTapped(type: historyToolbarElementType) { | |
145 | 149 | if type == .clean { |
146 | 150 | HistoryDBManager.shared.cleanHistory() |
147 | 151 | historyData.removeAll() |
... | ... | @@ -159,7 +163,8 @@ extension HistoryViewController { |
159 | 163 | filteredData = historyData |
160 | 164 | } |
161 | 165 | |
162 | - @objc private func searchBarTextChanged() { | |
166 | + @objc | |
167 | + private func searchBarTextChanged() { | |
163 | 168 | if let text = mainView.historySearchBar.searchTextFieldView.text { |
164 | 169 | if text.isEmpty { |
165 | 170 | filteredData = historyData |
... | ... | @@ -178,14 +183,14 @@ extension HistoryViewController: UITextFieldDelegate { |
178 | 183 | mainView.historySearchBar.searchTextFieldView.textColor = .black |
179 | 184 | } |
180 | 185 | |
181 | - func setupSearchBar() { | |
186 | + private func setupSearchBar() { | |
182 | 187 | mainView.historySearchBar.searchTextFieldView.delegate = self |
183 | 188 | } |
184 | 189 | } |
185 | 190 | |
186 | 191 | //MARK: History DB observe |
187 | 192 | extension HistoryViewController { |
188 | - func historyChangesObserve() { | |
193 | + private func historyChangesObserve() { | |
189 | 194 | let historyObjects = HistoryDBManager.shared.getHistory() |
190 | 195 | for historyObject in historyObjects { |
191 | 196 | objectNotificationToken = historyObject.observe { [self] changes in |
... | ... | @@ -195,7 +200,6 @@ extension HistoryViewController { |
195 | 200 | case .change(_, _): |
196 | 201 | break |
197 | 202 | case .deleted: |
198 | - print("Object deleted in Realm") | |
199 | 203 | self.historyData = HistoryDBManager.shared.getHistoryDataForTableView() |
200 | 204 | self.mainView.historyTabsTableView.reloadData() |
201 | 205 | } | ... | ... |
... | ... | @@ -4,18 +4,21 @@ |
4 | 4 | // |
5 | 5 | // Created by Artem Talko on 29.09.2023. |
6 | 6 | // |
7 | +//MARK: Checked | |
7 | 8 | |
8 | 9 | import UIKit |
9 | 10 | import SnapKit |
10 | 11 | |
11 | -class HistoryTableViewCell: UITableViewCell { | |
12 | +final class HistoryTableViewCell: UITableViewCell { | |
13 | + static let tabID = String(describing: HistoryTableViewCell.self) | |
14 | + | |
12 | 15 | var model: HistoryDataBase? { |
13 | 16 | didSet { |
14 | 17 | handleUI() |
15 | 18 | } |
16 | 19 | } |
17 | 20 | |
18 | - let searchImageLogo: UIImageView = { | |
21 | + private let searchImageLogo: UIImageView = { | |
19 | 22 | let obj = UIImageView() |
20 | 23 | obj.image = UIImage(systemName: "magnifyingglass") |
21 | 24 | obj.tintColor = .gray |
... | ... | @@ -23,20 +26,20 @@ class HistoryTableViewCell: UITableViewCell { |
23 | 26 | return obj |
24 | 27 | }() |
25 | 28 | |
26 | - let lastVisitSiteLabel: UILabel = { | |
29 | + private let lastVisitSiteLabel: UILabel = { | |
27 | 30 | let obj = UILabel() |
28 | 31 | obj.font = FontConstants.regularFont_14 |
29 | 32 | return obj |
30 | 33 | }() |
31 | 34 | |
32 | - let lastVisitSiteUrlLabel: UILabel = { | |
35 | + private let lastVisitSiteUrlLabel: UILabel = { | |
33 | 36 | let obj = UILabel() |
34 | 37 | obj.textColor = .gray |
35 | 38 | obj.font = FontConstants.regularFont_12 |
36 | 39 | return obj |
37 | 40 | }() |
38 | 41 | |
39 | - let lastVisitDateLabel: UILabel = { | |
42 | + private let lastVisitDateLabel: UILabel = { | |
40 | 43 | let obj = UILabel() |
41 | 44 | obj.font = FontConstants.regularFont_12 |
42 | 45 | obj.textColor = .gray |
... | ... | @@ -45,6 +48,7 @@ class HistoryTableViewCell: UITableViewCell { |
45 | 48 | |
46 | 49 | override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { |
47 | 50 | super.init(style: style, reuseIdentifier: reuseIdentifier) |
51 | + | |
48 | 52 | setup() |
49 | 53 | } |
50 | 54 | |
... | ... | @@ -57,6 +61,7 @@ class HistoryTableViewCell: UITableViewCell { |
57 | 61 | contentView.addSubview(lastVisitSiteLabel) |
58 | 62 | contentView.addSubview(lastVisitSiteUrlLabel) |
59 | 63 | contentView.addSubview(lastVisitDateLabel) |
64 | + | |
60 | 65 | setupConstraints() |
61 | 66 | } |
62 | 67 | |
... | ... | @@ -67,15 +72,18 @@ class HistoryTableViewCell: UITableViewCell { |
67 | 72 | make.height.equalTo(18.sizeW) |
68 | 73 | make.width.equalTo(18.sizeW) |
69 | 74 | } |
75 | + | |
70 | 76 | lastVisitSiteLabel.snp.makeConstraints { make in |
71 | 77 | make.leading.equalTo(searchImageLogo.snp.trailing).offset(8.sizeW) |
72 | 78 | make.trailing.equalTo(lastVisitDateLabel.snp.leading).offset(-8.sizeW) |
73 | 79 | make.top.equalToSuperview().inset(8.sizeH) |
74 | 80 | } |
81 | + | |
75 | 82 | lastVisitDateLabel.snp.makeConstraints { make in |
76 | 83 | make.trailing.equalToSuperview().inset(8.sizeW) |
77 | 84 | make.top.equalToSuperview().inset(8.sizeH) |
78 | 85 | } |
86 | + | |
79 | 87 | lastVisitSiteUrlLabel.snp.makeConstraints { make in |
80 | 88 | make.leading.equalToSuperview().offset(34.sizeW) |
81 | 89 | make.top.equalTo(lastVisitSiteLabel.snp.bottom).offset(4.sizeH) |
... | ... | @@ -88,6 +96,7 @@ class HistoryTableViewCell: UITableViewCell { |
88 | 96 | extension HistoryTableViewCell { |
89 | 97 | private func handleUI() { |
90 | 98 | let dateForLabel = DateManager.shared.getTimeFromDB(model?.lastVisit) |
99 | + | |
91 | 100 | lastVisitDateLabel.text = dateForLabel |
92 | 101 | lastVisitSiteLabel.text = model?.siteTitle |
93 | 102 | lastVisitSiteUrlLabel.text = model?.siteUrl | ... | ... |
... | ... | @@ -4,11 +4,12 @@ |
4 | 4 | // |
5 | 5 | // Created by Artem Talko on 01.10.2023. |
6 | 6 | // |
7 | +//MARK: Checked | |
7 | 8 | |
8 | 9 | import UIKit |
9 | 10 | |
10 | 11 | final class HistorySearchBarView: UIView { |
11 | - let searchImageView: UIImageView = { | |
12 | + private let searchImageView: UIImageView = { | |
12 | 13 | let obj = UIImageView() |
13 | 14 | let magnifyImage = UIImage(systemName: "magnifyingglass")?.withTintColor(.gray, renderingMode: .alwaysOriginal) |
14 | 15 | obj.image = magnifyImage |
... | ... | @@ -25,17 +26,19 @@ final class HistorySearchBarView: UIView { |
25 | 26 | |
26 | 27 | override init(frame: CGRect) { |
27 | 28 | super.init(frame: frame) |
28 | - setup() | |
29 | - setupConstraints() | |
29 | + | |
30 | + setupUI() | |
30 | 31 | } |
31 | 32 | |
32 | 33 | required init?(coder: NSCoder) { |
33 | 34 | fatalError("init(coder:) has not been implemented") |
34 | 35 | } |
35 | 36 | |
36 | - private func setup() { | |
37 | + private func setupUI() { | |
37 | 38 | addSubview(searchImageView) |
38 | 39 | addSubview(searchTextFieldView) |
40 | + | |
41 | + setupConstraints() | |
39 | 42 | } |
40 | 43 | |
41 | 44 | private func setupConstraints() { | ... | ... |
... | ... | @@ -4,6 +4,7 @@ |
4 | 4 | // |
5 | 5 | // Created by Artem Talko on 29.09.2023. |
6 | 6 | // |
7 | +//MARK: Checked | |
7 | 8 | |
8 | 9 | import UIKit |
9 | 10 | |
... | ... | @@ -14,7 +15,7 @@ enum historyToolbarElementType { |
14 | 15 | final class HistoryToolbarView: UIView { |
15 | 16 | var action: ((historyToolbarElementType) -> Void)? |
16 | 17 | |
17 | - let cleanHistoryButton: UIButton = { | |
18 | + private let cleanHistoryButton: UIButton = { | |
18 | 19 | let obj = UIButton() |
19 | 20 | obj.setTitle("Clean", for: .normal) |
20 | 21 | obj.setTitleColor(.systemBlue, for: .normal) |
... | ... | @@ -26,17 +27,18 @@ final class HistoryToolbarView: UIView { |
26 | 27 | |
27 | 28 | override init(frame: CGRect) { |
28 | 29 | super.init(frame: frame) |
29 | - setup() | |
30 | - setupConstraints() | |
30 | + setupUI() | |
31 | 31 | } |
32 | 32 | |
33 | 33 | required init?(coder: NSCoder) { |
34 | 34 | fatalError("init(coder:) has not been implemented") |
35 | 35 | } |
36 | 36 | |
37 | - private func setup() { | |
37 | + private func setupUI() { | |
38 | 38 | backgroundColor = .white |
39 | + | |
39 | 40 | addSubview(cleanHistoryButton) |
41 | + setupConstraints() | |
40 | 42 | } |
41 | 43 | |
42 | 44 | private func setupConstraints() { | ... | ... |
... | ... | @@ -4,7 +4,7 @@ |
4 | 4 | // |
5 | 5 | // Created by Artem Talko on 29.09.2023. |
6 | 6 | // |
7 | - | |
7 | +//MARK: Checked | |
8 | 8 | import UIKit |
9 | 9 | |
10 | 10 | final class HistoryView: UIView { |
... | ... | @@ -28,15 +28,16 @@ final class HistoryView: UIView { |
28 | 28 | |
29 | 29 | override init(frame: CGRect) { |
30 | 30 | super.init(frame: frame) |
31 | - setup() | |
31 | + setupUI() | |
32 | 32 | } |
33 | 33 | |
34 | 34 | required init?(coder: NSCoder) { |
35 | 35 | fatalError("init(coder:) has not been implemented") |
36 | 36 | } |
37 | 37 | |
38 | - private func setup() { | |
38 | + private func setupUI() { | |
39 | 39 | backgroundColor = .gray.withAlphaComponent(0.1) |
40 | + | |
40 | 41 | addSubview(historySearchBar) |
41 | 42 | addSubview(historyTabsTableView) |
42 | 43 | addSubview(historyToolbarView) |
... | ... | @@ -51,13 +52,14 @@ final class HistoryView: UIView { |
51 | 52 | |
52 | 53 | historyTabsTableView.snp.makeConstraints { make in |
53 | 54 | make.top.equalTo(historySearchBar.snp.bottom).offset(32.sizeH) |
54 | - make.bottom.equalTo(historyToolbarView.snp.top).inset(7.sizeH) | |
55 | 55 | make.leading.trailing.equalToSuperview().inset(16.sizeW) |
56 | + make.bottom.equalTo(historyToolbarView.snp.top).inset(7.sizeH) | |
56 | 57 | make.height.equalTo(600.sizeH) |
57 | 58 | } |
59 | + | |
58 | 60 | historyToolbarView.snp.makeConstraints { make in |
59 | - make.bottom.equalTo(safeAreaLayoutGuide.snp.bottom) | |
60 | 61 | make.leading.trailing.equalToSuperview() |
62 | + make.bottom.equalTo(safeAreaLayoutGuide.snp.bottom) | |
61 | 63 | } |
62 | 64 | } |
63 | 65 | } | ... | ... |
... | ... | @@ -4,6 +4,7 @@ |
4 | 4 | // |
5 | 5 | // Created by Artem Talko on 25.09.2023. |
6 | 6 | // |
7 | +//MARK: Checked | |
7 | 8 | |
8 | 9 | import UIKit |
9 | 10 | import SnapKit |
... | ... | @@ -12,19 +13,20 @@ import Combine |
12 | 13 | import Realm |
13 | 14 | |
14 | 15 | final class BrowserHomeViewController: UIViewController { |
16 | + let mainView = BrowserHomeView() | |
17 | + | |
18 | + private let searchingViewController: SearchingViewController | |
19 | + private let searchResultViewController: SearchResultViewController | |
20 | + private let tabsViewController: TabsViewController | |
21 | + | |
22 | + private var subscriptions: Set<AnyCancellable> | |
23 | + private var searchRequestURL: String | |
15 | 24 | private let images = StringConstants.browserHomeVCImages |
16 | - private let searchingViewController = SearchingViewController(dataForReq: []) | |
17 | - private let searchResultViewController = SearchResultViewController(searchLink: String()) | |
18 | - private var subscriptions: Set<AnyCancellable> = [] | |
19 | - private var finalSearchRequest = URLConstants.googleURL | |
20 | - private let tabsViewController = TabsViewController() | |
21 | 25 | private var currentTabId: Int? |
22 | 26 | |
23 | - let mainView = BrowserHomeView() | |
24 | - | |
25 | 27 | private var url: String? { |
26 | 28 | didSet { |
27 | - finalSearchRequest = url ?? String() | |
29 | + searchRequestURL = url ?? String() | |
28 | 30 | openSearchResult() |
29 | 31 | } |
30 | 32 | } |
... | ... | @@ -32,6 +34,7 @@ final class BrowserHomeViewController: UIViewController { |
32 | 34 | override func viewDidLoad() { |
33 | 35 | super.viewDidLoad() |
34 | 36 | view.backgroundColor = ColorConstants.lightGray |
37 | + | |
35 | 38 | initViewController() |
36 | 39 | } |
37 | 40 | |
... | ... | @@ -56,6 +59,13 @@ final class BrowserHomeViewController: UIViewController { |
56 | 59 | } |
57 | 60 | |
58 | 61 | init(url: String?, currentTabId: Int?) { |
62 | + searchResultViewController = SearchResultViewController(searchLink: String()) | |
63 | + searchingViewController = SearchingViewController(dataForReq: []) | |
64 | + tabsViewController = TabsViewController() | |
65 | + | |
66 | + subscriptions = [] | |
67 | + searchRequestURL = URLConstants.googleURL | |
68 | + | |
59 | 69 | super.init(nibName: nil, bundle: nil) |
60 | 70 | self.url = url |
61 | 71 | self.currentTabId = currentTabId |
... | ... | @@ -79,41 +89,36 @@ extension BrowserHomeViewController: UICollectionViewDataSource, UICollectionVie |
79 | 89 | } |
80 | 90 | |
81 | 91 | func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { |
82 | - guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "TabCollectionViewCell", for: indexPath) as? TabCollectionViewCell else { | |
92 | + guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: TabCollectionViewCell.cellID, for: indexPath) as? TabCollectionViewCell else { | |
83 | 93 | return TabCollectionViewCell() |
84 | 94 | } |
85 | 95 | let finalCell = setupCellForCollectionView(cell, indexPath) |
96 | + | |
86 | 97 | return finalCell |
87 | 98 | } |
88 | 99 | |
89 | - private func setupCellForCollectionView(_ cell: TabCollectionViewCell, _ indexPath: IndexPath) -> TabCollectionViewCell { | |
100 | + func setupCellForCollectionView(_ cell: TabCollectionViewCell, _ indexPath: IndexPath) -> TabCollectionViewCell { | |
90 | 101 | let imageName = images[indexPath.item] |
91 | 102 | cell.tabCellImage.image = UIImage(named: imageName) |
92 | 103 | cell.tabCellLabel.text = imageName |
93 | - cell.backgroundColor = .white | |
104 | + | |
94 | 105 | return cell |
95 | 106 | } |
96 | 107 | |
97 | 108 | func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { |
98 | - return CGSize(width: 72.sizeW, height: 94.sizeH) | |
109 | + return CGSize(width: 72.sizeW, height: 104.sizeH) | |
99 | 110 | } |
100 | 111 | |
101 | 112 | func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { |
102 | - finalSearchRequest = StringConstants.browserHomeVCurl[indexPath.row] | |
113 | + searchRequestURL = StringConstants.browserHomeVCurl[indexPath.row] | |
103 | 114 | openSearchResult() |
104 | 115 | } |
105 | - | |
106 | - private func setupCollectionView() { | |
107 | - mainView.frequentlyVisitedCollectionView.dataSource = self | |
108 | - mainView.frequentlyVisitedCollectionView.delegate = self | |
109 | - mainView.frequentlyVisitedCollectionView.register(TabCollectionViewCell.self, forCellWithReuseIdentifier: "TabCollectionViewCell") | |
110 | - } | |
111 | 116 | } |
112 | 117 | |
113 | 118 | |
114 | 119 | //MARK: - Keyboard extention |
115 | 120 | extension BrowserHomeViewController { |
116 | - func keyboardObserver() { | |
121 | + private func keyboardObserver() { | |
117 | 122 | NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillDisappear), name: UIResponder.keyboardWillHideNotification, object: nil) |
118 | 123 | NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow), name: UIResponder.keyboardWillShowNotification, object: nil) |
119 | 124 | } |
... | ... | @@ -122,29 +127,39 @@ extension BrowserHomeViewController { |
122 | 127 | |
123 | 128 | //MARK: - Action |
124 | 129 | extension BrowserHomeViewController { |
125 | - @objc private func searchResultAction() { | |
126 | - removeChildViewController() | |
127 | - mainView.searchBarContainer.searchBarView.searchTextFieldView.text = nil | |
128 | - mainView.searchBarContainer.searchBarView.cleanTextFieldButton.isHidden = true | |
130 | + @objc | |
131 | + private func searchBarTextChanged() { | |
132 | + if let text = mainView.searchBarContainer.searchBarView.searchTextFieldView.text { | |
133 | + searchRequestURL = text | |
134 | + mainView.searchBarContainer.searchBarView.cleanTextFieldButton.isHidden = false | |
135 | + if searchRequestURL.isEmpty { | |
136 | + searchResultAction() | |
137 | + } else { | |
138 | + Task { | |
139 | + await searchAndReloadTableView() | |
140 | + } | |
141 | + } | |
142 | + } | |
129 | 143 | } |
130 | 144 | |
131 | - func searchAndReloadTableView() async { | |
132 | - let sitesFromSearch: [String] = await BrowserSearchService().searchSuggest(finalSearchRequest) | |
133 | - if !sitesFromSearch.isEmpty { | |
134 | - searchingViewController.dataForReq = sitesFromSearch | |
135 | - } | |
136 | - addingSearchingViewController(searchingViewController) | |
145 | + @objc | |
146 | + private func searchResultAction() { | |
147 | + mainView.searchBarContainer.searchBarView.searchTextFieldView.text = nil | |
148 | + mainView.searchBarContainer.searchBarView.cleanTextFieldButton.isHidden = true | |
149 | + | |
150 | + removeChildViewController() | |
137 | 151 | } |
138 | 152 | |
139 | 153 | @objc |
140 | - func keyboardWillShow(_ notification: Notification) { | |
141 | - guard let keyboardFrame = notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect else { return } | |
154 | + private func keyboardWillShow(_ notification: Notification) { | |
155 | + guard let keyboardFrame = notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect else { return | |
156 | + } | |
142 | 157 | let keyboardHeight = keyboardFrame.height |
143 | 158 | self.mainView.animateSearchBar(keyboardHeight) |
144 | 159 | } |
145 | 160 | |
146 | 161 | @objc |
147 | - func keyboardWillDisappear() { | |
162 | + private func keyboardWillDisappear() { | |
148 | 163 | mainView.animateSearchBarDismiss() |
149 | 164 | } |
150 | 165 | |
... | ... | @@ -164,8 +179,12 @@ extension BrowserHomeViewController { |
164 | 179 | private func removeSearchingViewController(_ sender: UIButton) { |
165 | 180 | searchResultAction() |
166 | 181 | } |
167 | - | |
168 | - func didTabButtonTapped(type: ToolbarElementType) { | |
182 | +} | |
183 | + | |
184 | + | |
185 | +//MARK: - Helpers | |
186 | +extension BrowserHomeViewController { | |
187 | + private func didTabButtonTapped(type: ToolbarElementType) { | |
169 | 188 | switch type { |
170 | 189 | case .history: |
171 | 190 | let historyViewController = HistoryViewController() |
... | ... | @@ -181,17 +200,27 @@ extension BrowserHomeViewController { |
181 | 200 | searchResultViewController.mainView.searchResultView.goForward() |
182 | 201 | break |
183 | 202 | case .share: |
184 | - let items = [URL(string: finalSearchRequest)] | |
203 | + let items = [URL(string: searchRequestURL)] | |
185 | 204 | let shareView = UIActivityViewController(activityItems: items as [Any], applicationActivities: nil) |
186 | 205 | present(shareView, animated: true) |
187 | 206 | break |
188 | 207 | } |
189 | 208 | } |
190 | -} | |
191 | - | |
192 | - | |
193 | -//MARK: - Helpers | |
194 | -extension BrowserHomeViewController { | |
209 | + | |
210 | + private func searchAndReloadTableView() async { | |
211 | + let sitesFromSearch: [String] = await BrowserSearchService().searchSuggest(searchRequestURL) | |
212 | + if !sitesFromSearch.isEmpty { | |
213 | + searchingViewController.searchRequestData = sitesFromSearch | |
214 | + } | |
215 | + addingSearchingViewController(searchingViewController) | |
216 | + } | |
217 | + | |
218 | + private func setupCollectionView() { | |
219 | + mainView.frequentlyVisitedCollectionView.dataSource = self | |
220 | + mainView.frequentlyVisitedCollectionView.delegate = self | |
221 | + mainView.frequentlyVisitedCollectionView.register(TabCollectionViewCell.self, forCellWithReuseIdentifier: TabCollectionViewCell.cellID) | |
222 | + } | |
223 | + | |
195 | 224 | private func addTargets() { |
196 | 225 | mainView.settingButton.addTarget(self, action: #selector(settingButtonTapped(_ :)), for: .touchUpInside) |
197 | 226 | mainView.removeAddButton.addTarget(self, action: #selector(removeAdButtonTapped(_ :)), for: .touchUpInside) |
... | ... | @@ -214,23 +243,22 @@ extension BrowserHomeViewController { |
214 | 243 | guard let cell = cell as? SearchingTableViewCell else { |
215 | 244 | return |
216 | 245 | } |
217 | - finalSearchRequest = "https://www.google.com/search?q=" + (cell.searchLabel.text ?? "") | |
246 | + searchRequestURL = "https://www.google.com/search?q=" + (cell.searchLabel.text ?? "") | |
218 | 247 | openSearchResult() |
219 | 248 | mainView.searchBarContainer.searchBarView.searchTextFieldView.endEditing(true) |
220 | 249 | } |
221 | 250 | } |
222 | 251 | |
223 | 252 | private func openSearchResult() { |
224 | - let finalSearchRequest = finalSearchRequest.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) | |
253 | + let finalSearchRequest = searchRequestURL.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) | |
225 | 254 | searchResultViewController.searchLink = finalSearchRequest ?? "" |
226 | 255 | if let localUrl = URL(string: finalSearchRequest ?? "") { |
227 | 256 | let request = URLRequest(url: localUrl) |
228 | - print(request) | |
229 | 257 | searchResultViewController.mainView.searchResultView.load(request) |
230 | 258 | } |
231 | 259 | addingSearchingViewController(searchResultViewController) |
232 | 260 | } |
233 | - | |
261 | + | |
234 | 262 | private func tabsButtonHandler() { |
235 | 263 | if currentTabId == nil { |
236 | 264 | addNewTab() |
... | ... | @@ -263,36 +291,36 @@ extension BrowserHomeViewController { |
263 | 291 | } |
264 | 292 | } |
265 | 293 | |
266 | - private func updateCurrentTab() { | |
267 | - let allTabs = TabManager.shared.getAllTabs() | |
268 | - let chosenTab = allTabs[self.currentTabId ?? Int()] | |
269 | - let gottedCellId = chosenTab.tabId | |
270 | - let imageForUpdatedTab = SnapshotService.shared.makeSnapshot(self.mainView) | |
271 | - if let childViewController = self.children.first as? SearchResultViewController { | |
272 | - guard let siteTitle = childViewController.mainView.searchResultView.title else { | |
273 | - return | |
274 | - } | |
275 | - guard let siteUrl = childViewController.mainView.searchResultView.url?.absoluteString else { | |
276 | - return | |
277 | - } | |
278 | - let lastDate = DateManager.shared.currentDate | |
279 | - | |
280 | - TabManager.shared.updateTab(tabId: gottedCellId, newTabTitle: siteTitle, newSnapshotImage: imageForUpdatedTab, newTabUrl: siteUrl) { result in | |
281 | - self.navigationController?.popViewController(animated: true) | |
282 | - } | |
283 | - HistoryDBManager.shared.saveToHistory(siteTitle: siteTitle, siteUrl: siteUrl, lastVisit: lastDate) | |
284 | - } else { | |
285 | - TabManager.shared.updateTab(tabId: gottedCellId, newTabTitle: "Start Page", newSnapshotImage: imageForUpdatedTab, newTabUrl: "homeUrl") { result in | |
286 | - self.navigationController?.popViewController(animated: true) | |
287 | - } | |
288 | - } | |
289 | - } | |
294 | + private func updateCurrentTab() { | |
295 | + let allTabs = TabManager.shared.getAllTabs() | |
296 | + let chosenTab = allTabs[self.currentTabId ?? Int()] | |
297 | + let gottedCellId = chosenTab.tabId | |
298 | + let imageForUpdatedTab = SnapshotService.shared.makeSnapshot(self.mainView) | |
299 | + if let childViewController = self.children.first as? SearchResultViewController { | |
300 | + guard let siteTitle = childViewController.mainView.searchResultView.title else { | |
301 | + return | |
302 | + } | |
303 | + guard let siteUrl = childViewController.mainView.searchResultView.url?.absoluteString else { | |
304 | + return | |
305 | + } | |
306 | + let lastDate = DateManager.shared.currentDate | |
307 | + | |
308 | + TabManager.shared.updateTab(tabId: gottedCellId, newTabTitle: siteTitle, newSnapshotImage: imageForUpdatedTab, newTabUrl: siteUrl) { result in | |
309 | + self.navigationController?.popViewController(animated: true) | |
310 | + } | |
311 | + HistoryDBManager.shared.saveToHistory(siteTitle: siteTitle, siteUrl: siteUrl, lastVisit: lastDate) | |
312 | + } else { | |
313 | + TabManager.shared.updateTab(tabId: gottedCellId, newTabTitle: "Start Page", newSnapshotImage: imageForUpdatedTab, newTabUrl: "homeUrl") { result in | |
314 | + self.navigationController?.popViewController(animated: true) | |
315 | + } | |
316 | + } | |
317 | + } | |
290 | 318 | } |
291 | 319 | |
292 | 320 | |
293 | 321 | //MARK: - ChildVC actions |
294 | 322 | extension BrowserHomeViewController { |
295 | - func addingSearchingViewController(_ childViewController: UIViewController) { | |
323 | + private func addingSearchingViewController(_ childViewController: UIViewController) { | |
296 | 324 | if self.children.isEmpty { |
297 | 325 | addNewChildViewController(childViewController) |
298 | 326 | } else { |
... | ... | @@ -301,13 +329,14 @@ extension BrowserHomeViewController { |
301 | 329 | } |
302 | 330 | } |
303 | 331 | |
304 | - func addNewChildViewController(_ child: UIViewController) { | |
305 | - addChild(child) | |
332 | + private func addNewChildViewController(_ child: UIViewController) { | |
306 | 333 | mainView.addSearchView(child.view) |
307 | 334 | child.didMove(toParent: self) |
335 | + | |
336 | + addChild(child) | |
308 | 337 | } |
309 | 338 | |
310 | - func removeChildViewController() { | |
339 | + private func removeChildViewController() { | |
311 | 340 | if let childViewController = self.children.first as? SearchingViewController { |
312 | 341 | childViewController.view.removeFromSuperview() |
313 | 342 | childViewController.willMove(toParent: nil) |
... | ... | @@ -324,93 +353,81 @@ extension BrowserHomeViewController { |
324 | 353 | |
325 | 354 | //MARK: - SearchBar extention |
326 | 355 | extension BrowserHomeViewController: UITextFieldDelegate { |
327 | - @objc | |
328 | - func searchBarTextChanged() { | |
329 | - if let text = mainView.searchBarContainer.searchBarView.searchTextFieldView.text { | |
330 | - finalSearchRequest = text | |
331 | - mainView.searchBarContainer.searchBarView.cleanTextFieldButton.isHidden = false | |
332 | - if finalSearchRequest.isEmpty { | |
333 | - searchResultAction() | |
334 | - } else { | |
335 | - Task { | |
336 | - await searchAndReloadTableView() | |
337 | - } | |
338 | - } | |
339 | - } | |
340 | - } | |
341 | - | |
342 | 356 | func textFieldDidBeginEditing(_ textField: UITextField) { |
343 | 357 | mainView.searchBarContainer.searchBarView.searchTextFieldView.text = nil |
344 | 358 | mainView.searchBarContainer.searchBarView.searchTextFieldView.textColor = .black |
345 | 359 | } |
346 | 360 | |
347 | 361 | func textFieldShouldReturn(_ textField: UITextField) -> Bool { |
348 | - finalSearchRequest = "https://www.google.com/search?q=" + (textField.text ?? "") | |
349 | - openSearchResult() | |
350 | 362 | textField.resignFirstResponder() |
363 | + | |
364 | + searchRequestURL = "https://www.google.com/search?q=" + (textField.text ?? "") | |
365 | + openSearchResult() | |
366 | + | |
351 | 367 | return true |
352 | 368 | } |
353 | 369 | |
354 | 370 | func setupSearchBarComponentsAction() { |
355 | 371 | mainView.searchBarContainer.searchBarView.searchTextFieldView.autocorrectionType = .no |
356 | - isButtonClickable() | |
357 | 372 | mainView.searchBarContainer.searchBarView.searchTextFieldView.delegate = self |
358 | 373 | mainView.searchBarContainer.searchBarView.cleanTextFieldButton.addTarget(self, action: #selector(searchResultAction), for: .touchUpInside) |
374 | + buttonObserver() | |
359 | 375 | } |
360 | 376 | } |
361 | 377 | |
362 | 378 | |
363 | 379 | //MARK: - WebView extention |
364 | 380 | extension BrowserHomeViewController { |
365 | - func isButtonClickable() { | |
366 | - searchResultViewController.mainView.searchResultView | |
367 | - .publisher(for: \.canGoBack) | |
368 | - .sink { [weak self] canGoBack in | |
369 | - self?.mainView.toolbarView.backBarButtonItem.isEnabled = canGoBack | |
370 | - } | |
371 | - .store(in: &subscriptions) | |
372 | - | |
373 | - searchResultViewController.mainView.searchResultView | |
374 | - .publisher(for: \.canGoForward) | |
375 | - .sink { [weak self] canGoForward in | |
376 | - self?.mainView.toolbarView.forwardBarButtonItem.isEnabled = canGoForward | |
377 | - } | |
378 | - .store(in: &subscriptions) | |
379 | - | |
380 | - searchResultViewController.mainView.searchResultView | |
381 | - .publisher(for: \.isLoading) | |
382 | - .sink { [weak self] isLoading in | |
383 | - guard let self = self else { return } | |
384 | - if let url = self.searchResultViewController.mainView.searchResultView.url { | |
385 | - self.finalSearchRequest = url.absoluteString | |
386 | - } | |
381 | + private func buttonObserver() { | |
382 | + searchResultViewController.mainView.searchResultView | |
383 | + .publisher(for: \.canGoBack) | |
384 | + .sink { [weak self] canGoBack in | |
385 | + self?.mainView.toolbarView.backBarButtonItem.isEnabled = canGoBack | |
386 | + } | |
387 | + .store(in: &subscriptions) | |
388 | + | |
389 | + searchResultViewController.mainView.searchResultView | |
390 | + .publisher(for: \.canGoForward) | |
391 | + .sink { [weak self] canGoForward in | |
392 | + self?.mainView.toolbarView.forwardBarButtonItem.isEnabled = canGoForward | |
393 | + } | |
394 | + .store(in: &subscriptions) | |
395 | + | |
396 | + searchResultViewController.mainView.searchResultView | |
397 | + .publisher(for: \.isLoading) | |
398 | + .sink { [weak self] isLoading in | |
399 | + guard let self = self else { return } | |
400 | + if let url = self.searchResultViewController.mainView.searchResultView.url { | |
401 | + self.searchRequestURL = url.absoluteString | |
387 | 402 | } |
388 | - .store(in: &subscriptions) | |
389 | - } | |
390 | - | |
391 | - private func progressObserver() { | |
392 | - searchResultViewController.mainView.searchResultView | |
393 | - .publisher(for: \.estimatedProgress) | |
394 | - .sink { [weak self] progress in | |
395 | - guard let self = self else { return } | |
396 | - self.mainView.searchBarContainer.searchBarView.progressBar.progress = Float(progress) | |
397 | - if progress == 1 { | |
398 | - self.mainView.searchBarContainer.searchBarView.progressBar.isHidden = true | |
399 | - self.mainView.toolbarView.shareBarButtonItem.isEnabled = true | |
400 | - } else if progress == 0 { | |
401 | - self.mainView.searchBarContainer.searchBarView.progressBar.isHidden = true | |
402 | - } else { | |
403 | - self.mainView.searchBarContainer.searchBarView.progressBar.isHidden = false | |
404 | - self.mainView.toolbarView.shareBarButtonItem.isEnabled = false | |
405 | - } | |
403 | + } | |
404 | + .store(in: &subscriptions) | |
405 | + } | |
406 | + | |
407 | + private func progressObserver() { | |
408 | + searchResultViewController.mainView.searchResultView | |
409 | + .publisher(for: \.estimatedProgress) | |
410 | + .sink { [weak self] progress in | |
411 | + guard let self = self else { return } | |
412 | + self.mainView.searchBarContainer.searchBarView.progressBar.progress = Float(progress) | |
413 | + if progress == 1 { | |
414 | + self.mainView.searchBarContainer.searchBarView.progressBar.isHidden = true | |
415 | + self.mainView.toolbarView.shareBarButtonItem.isEnabled = true | |
416 | + } else if progress == 0 { | |
417 | + self.mainView.searchBarContainer.searchBarView.progressBar.isHidden = true | |
418 | + } else { | |
419 | + self.mainView.searchBarContainer.searchBarView.progressBar.isHidden = false | |
420 | + self.mainView.toolbarView.shareBarButtonItem.isEnabled = false | |
406 | 421 | } |
407 | - .store(in: &subscriptions) | |
408 | - } | |
422 | + } | |
423 | + .store(in: &subscriptions) | |
409 | 424 | } |
425 | +} | |
410 | 426 | |
427 | +//MARK: Url managment | |
411 | 428 | extension BrowserHomeViewController { |
412 | 429 | func urlManagment(_ url: String) { |
413 | - finalSearchRequest = url | |
430 | + searchRequestURL = url | |
414 | 431 | openSearchResult() |
415 | 432 | } |
416 | 433 | } | ... | ... |
... | ... | @@ -4,6 +4,7 @@ |
4 | 4 | // |
5 | 5 | // Created by Artem Talko on 25.09.2023. |
6 | 6 | // |
7 | +//MARK: Checked | |
7 | 8 | |
8 | 9 | import UIKit |
9 | 10 | import SnapKit |
... | ... | @@ -21,19 +22,22 @@ final class BrowserHomeView: UIView { |
21 | 22 | obj.contentEdgeInsets = UIEdgeInsets(top: 10.sizeW, left: 10.sizeW, bottom: 10.sizeW, right: 10.sizeW) |
22 | 23 | obj.clipsToBounds = true |
23 | 24 | obj.layer.masksToBounds = false |
25 | + | |
24 | 26 | return obj |
25 | 27 | }() |
26 | 28 | |
27 | 29 | let settingButton: UIButton = { |
28 | 30 | let obj = UIButton() |
29 | 31 | obj.setImage(UIImage(named: "Settings")?.withTintColor(.systemBlue), for: .normal) |
32 | + | |
30 | 33 | return obj |
31 | 34 | }() |
32 | 35 | |
33 | - let titleLabel: UILabel = { | |
36 | + private let titleLabel: UILabel = { | |
34 | 37 | let obj = UILabel() |
35 | 38 | obj.text = StringConstants.frequentlyVisited |
36 | 39 | obj.font = FontConstants.semiboldFont_18 |
40 | + | |
37 | 41 | return obj |
38 | 42 | }() |
39 | 43 | |
... | ... | @@ -46,24 +50,27 @@ final class BrowserHomeView: UIView { |
46 | 50 | let collectionView = UICollectionView(frame: .zero, collectionViewLayout: obj) |
47 | 51 | collectionView.backgroundColor = .clear |
48 | 52 | collectionView.showsHorizontalScrollIndicator = false |
53 | + | |
49 | 54 | return collectionView |
50 | 55 | }() |
51 | 56 | |
52 | 57 | let toolbarView: ToolbarView = { |
53 | 58 | let obj = ToolbarView() |
59 | + | |
54 | 60 | return obj |
55 | 61 | }() |
56 | 62 | |
57 | 63 | let searchBarContainer: SearchBarContainer = { |
58 | 64 | let obj = SearchBarContainer() |
59 | 65 | obj.backgroundColor = .clear |
66 | + | |
60 | 67 | return obj |
61 | 68 | }() |
62 | 69 | |
63 | 70 | override init(frame: CGRect) { |
64 | 71 | super.init(frame: frame) |
72 | + | |
65 | 73 | setup() |
66 | - setupConstraints() | |
67 | 74 | } |
68 | 75 | |
69 | 76 | required init?(coder: NSCoder) { |
... | ... | @@ -77,6 +84,8 @@ final class BrowserHomeView: UIView { |
77 | 84 | addSubview(settingButton) |
78 | 85 | addSubview(searchBarContainer) |
79 | 86 | addSubview(toolbarView) |
87 | + | |
88 | + setupConstraints() | |
80 | 89 | } |
81 | 90 | |
82 | 91 | private func setupConstraints() { |
... | ... | @@ -86,29 +95,29 @@ final class BrowserHomeView: UIView { |
86 | 95 | make.trailing.equalToSuperview().offset(-158.sizeW) |
87 | 96 | } |
88 | 97 | settingButton.snp.makeConstraints { make in |
89 | - make.centerY.equalTo(removeAddButton) | |
98 | + make.trailing.equalToSuperview().offset(-16.sizeW) | |
90 | 99 | make.height.equalTo(24.sizeH) |
91 | 100 | make.width.equalTo(24.sizeH) |
92 | - make.trailing.equalToSuperview().offset(-16.sizeW) | |
101 | + make.centerY.equalTo(removeAddButton) | |
93 | 102 | } |
94 | 103 | titleLabel.snp.makeConstraints { make in |
95 | 104 | make.top.equalTo(removeAddButton.snp.bottom).offset(64.sizeH) |
96 | 105 | make.leading.equalTo(safeAreaLayoutGuide.snp.leading).offset(16.sizeW) |
97 | 106 | } |
98 | 107 | frequentlyVisitedCollectionView.snp.makeConstraints { make in |
108 | + make.top.equalTo(titleLabel.snp.bottom).offset(8.sizeH) | |
99 | 109 | make.leading.trailing.equalToSuperview().inset(24.sizeW) |
100 | 110 | make.height.equalTo(120.sizeH) |
101 | - make.top.equalTo(titleLabel.snp.bottom).offset(8.sizeH) | |
102 | 111 | } |
103 | 112 | toolbarView.snp.makeConstraints { make in |
104 | 113 | make.leading.equalToSuperview() |
105 | - make.trailing.equalToSuperview() | |
106 | 114 | make.bottom.equalTo(safeAreaLayoutGuide.snp.bottom) |
115 | + make.trailing.equalToSuperview() | |
107 | 116 | } |
108 | 117 | searchBarContainer.snp.makeConstraints { make in |
109 | 118 | make.leading.equalToSuperview() |
110 | - make.trailing.equalToSuperview() | |
111 | 119 | make.bottom.equalToSuperview().offset(-90.sizeH) |
120 | + make.trailing.equalToSuperview() | |
112 | 121 | } |
113 | 122 | } |
114 | 123 | } |
... | ... | @@ -117,6 +126,7 @@ final class BrowserHomeView: UIView { |
117 | 126 | extension BrowserHomeView { |
118 | 127 | func addSearchView(_ childView: UIView){ |
119 | 128 | addSubview(childView) |
129 | + | |
120 | 130 | childView.snp.makeConstraints { make in |
121 | 131 | make.top.equalToSuperview() |
122 | 132 | make.leading.trailing.equalToSuperview() | ... | ... |
... | ... | @@ -4,13 +4,17 @@ |
4 | 4 | // |
5 | 5 | // Created by Artem Talko on 25.09.2023. |
6 | 6 | // |
7 | +//MARK: Checked | |
7 | 8 | |
8 | 9 | import UIKit |
9 | 10 | |
10 | 11 | final class TabCollectionViewCell: UICollectionViewCell { |
12 | + static let cellID = String(describing: TabCollectionViewCell.self) | |
13 | + | |
11 | 14 | let tabCellImage: UIImageView = { |
12 | 15 | let obj = UIImageView() |
13 | 16 | obj.contentMode = .scaleToFill |
17 | + | |
14 | 18 | return obj |
15 | 19 | }() |
16 | 20 | |
... | ... | @@ -18,11 +22,13 @@ final class TabCollectionViewCell: UICollectionViewCell { |
18 | 22 | let obj = UILabel() |
19 | 23 | obj.textColor = .black |
20 | 24 | obj.font = FontConstants.regularFont_14 |
25 | + | |
21 | 26 | return obj |
22 | 27 | }() |
23 | 28 | |
24 | 29 | override init(frame: CGRect) { |
25 | 30 | super.init(frame: frame) |
31 | + | |
26 | 32 | setup() |
27 | 33 | } |
28 | 34 | |
... | ... | @@ -30,13 +36,14 @@ final class TabCollectionViewCell: UICollectionViewCell { |
30 | 36 | fatalError("init(coder:) has not been implemented") |
31 | 37 | } |
32 | 38 | |
33 | - func setup() { | |
34 | - | |
39 | + private func setup() { | |
40 | + backgroundColor = .white | |
35 | 41 | layer.cornerRadius = 10 |
36 | 42 | contentView.backgroundColor = UIColor(red: 0.867, green: 0.867, blue: 0.863, alpha: 0.4) |
37 | 43 | contentView.layer.cornerRadius = 10 |
38 | 44 | contentView.addSubview(tabCellImage) |
39 | 45 | contentView.addSubview(tabCellLabel) |
46 | + | |
40 | 47 | setupConstraints() |
41 | 48 | } |
42 | 49 | |
... | ... | @@ -48,13 +55,14 @@ final class TabCollectionViewCell: UICollectionViewCell { |
48 | 55 | } |
49 | 56 | |
50 | 57 | tabCellLabel.snp.makeConstraints { make in |
51 | - make.centerX.equalToSuperview() | |
52 | 58 | make.top.equalTo(tabCellImage.snp.bottom).offset(8.sizeH) |
59 | + make.centerX.equalToSuperview() | |
53 | 60 | } |
54 | 61 | } |
55 | 62 | |
56 | 63 | override func layoutSubviews() { |
57 | 64 | super.layoutSubviews() |
65 | + | |
58 | 66 | shadowSetup() |
59 | 67 | } |
60 | 68 | } | ... | ... |
... | ... | @@ -4,6 +4,7 @@ |
4 | 4 | // |
5 | 5 | // Created by Artem Talko on 12.10.2023. |
6 | 6 | // |
7 | +//MARK: Checked | |
7 | 8 | |
8 | 9 | import UIKit |
9 | 10 | |
... | ... | @@ -16,13 +17,14 @@ final class SearchBarContainer: UIView { |
16 | 17 | obj.layer.shadowOpacity = 1 |
17 | 18 | obj.layer.shadowRadius = 10 |
18 | 19 | obj.layer.shadowOffset = CGSize(width: 0, height: 4.sizeW) |
20 | + | |
19 | 21 | return obj |
20 | 22 | }() |
21 | 23 | |
22 | 24 | override init(frame: CGRect) { |
23 | 25 | super.init(frame: frame) |
26 | + | |
24 | 27 | setup() |
25 | - setupConstraints() | |
26 | 28 | } |
27 | 29 | |
28 | 30 | required init?(coder: NSCoder) { |
... | ... | @@ -31,14 +33,16 @@ final class SearchBarContainer: UIView { |
31 | 33 | |
32 | 34 | private func setup() { |
33 | 35 | addSubview(searchBarView) |
36 | + | |
37 | + setupConstraints() | |
34 | 38 | } |
35 | 39 | |
36 | 40 | private func setupConstraints() { |
37 | 41 | searchBarView.snp.makeConstraints { make in |
38 | 42 | make.top.equalToSuperview().offset(4.sizeH) |
39 | 43 | make.leading.equalToSuperview().offset(16.sizeW) |
40 | - make.trailing.equalToSuperview().offset(-16.sizeW) | |
41 | 44 | make.bottom.equalToSuperview().offset(-6.sizeH) |
45 | + make.trailing.equalToSuperview().offset(-16.sizeW) | |
42 | 46 | } |
43 | 47 | } |
44 | 48 | } | ... | ... |
... | ... | @@ -4,14 +4,16 @@ |
4 | 4 | // |
5 | 5 | // Created by Artem Talko on 26.09.2023. |
6 | 6 | // |
7 | +//MARK: Checked | |
7 | 8 | |
8 | 9 | import UIKit |
9 | 10 | |
10 | 11 | final class SearchBarView: UIView { |
11 | - let searchImageView: UIImageView = { | |
12 | + private let searchImageView: UIImageView = { | |
12 | 13 | let obj = UIImageView() |
13 | 14 | let magnifyImage = UIImage(systemName: "magnifyingglass")?.withTintColor(.gray, renderingMode: .alwaysOriginal) |
14 | 15 | obj.image = magnifyImage |
16 | + | |
15 | 17 | return obj |
16 | 18 | }() |
17 | 19 | |
... | ... | @@ -19,6 +21,7 @@ final class SearchBarView: UIView { |
19 | 21 | let obj = UITextField() |
20 | 22 | obj.text = "Search" |
21 | 23 | obj.textColor = ColorConstants.gray |
24 | + | |
22 | 25 | return obj |
23 | 26 | }() |
24 | 27 | |
... | ... | @@ -27,6 +30,7 @@ final class SearchBarView: UIView { |
27 | 30 | obj.setImage(UIImage(systemName: "xmark.circle.fill"), for: .normal) |
28 | 31 | obj.tintColor = .black |
29 | 32 | obj.isHidden = true |
33 | + | |
30 | 34 | return obj |
31 | 35 | }() |
32 | 36 | |
... | ... | @@ -35,13 +39,14 @@ final class SearchBarView: UIView { |
35 | 39 | obj.progressTintColor = .systemIndigo |
36 | 40 | obj.progress = 0 |
37 | 41 | obj.translatesAutoresizingMaskIntoConstraints = false |
42 | + | |
38 | 43 | return obj |
39 | 44 | }() |
40 | 45 | |
41 | 46 | override init(frame: CGRect) { |
42 | 47 | super.init(frame: frame) |
48 | + | |
43 | 49 | setup() |
44 | - setupConstraints() | |
45 | 50 | } |
46 | 51 | |
47 | 52 | required init?(coder: NSCoder) { |
... | ... | @@ -53,25 +58,30 @@ final class SearchBarView: UIView { |
53 | 58 | addSubview(searchImageView) |
54 | 59 | addSubview(searchTextFieldView) |
55 | 60 | addSubview(cleanTextFieldButton) |
61 | + | |
62 | + setupConstraints() | |
56 | 63 | } |
57 | 64 | |
58 | 65 | private func setupConstraints() { |
59 | 66 | searchImageView.snp.makeConstraints { make in |
60 | - make.leading.equalToSuperview().offset(16.sizeW) | |
61 | 67 | make.top.bottom.equalToSuperview().inset(8.sizeH) |
68 | + make.leading.equalToSuperview().offset(16.sizeW) | |
62 | 69 | } |
70 | + | |
63 | 71 | searchTextFieldView.snp.makeConstraints { make in |
72 | + make.top.bottom.equalToSuperview().inset(8.sizeH) | |
64 | 73 | make.leading.equalTo(searchImageView).offset(32.sizeW) |
65 | 74 | make.trailing.equalToSuperview().offset(-16.sizeW) |
66 | - make.top.bottom.equalToSuperview().inset(8.sizeH) | |
67 | 75 | } |
76 | + | |
68 | 77 | cleanTextFieldButton.snp.makeConstraints { make in |
69 | - make.trailing.equalToSuperview().offset(-16.sizeW) | |
70 | 78 | make.top.bottom.equalToSuperview().inset(8.sizeH) |
79 | + make.trailing.equalToSuperview().offset(-16.sizeW) | |
71 | 80 | } |
81 | + | |
72 | 82 | progressBar.snp.makeConstraints { make in |
73 | - make.bottom.equalToSuperview().inset(2.sizeH) | |
74 | 83 | make.leading.trailing.equalToSuperview() |
84 | + make.bottom.equalToSuperview().inset(2.sizeH) | |
75 | 85 | make.height.equalTo(2) |
76 | 86 | } |
77 | 87 | } | ... | ... |
... | ... | @@ -4,6 +4,7 @@ |
4 | 4 | // |
5 | 5 | // Created by Artem Talko on 27.09.2023. |
6 | 6 | // |
7 | +//MARK: Checked | |
7 | 8 | |
8 | 9 | import UIKit |
9 | 10 | |
... | ... | @@ -18,11 +19,12 @@ enum ToolbarElementType { |
18 | 19 | final class ToolbarView: UIView { |
19 | 20 | var action: ((ToolbarElementType) -> Void)? |
20 | 21 | |
21 | - let toolbar: UIToolbar = { | |
22 | + private let toolbar: UIToolbar = { | |
22 | 23 | let obj = UIToolbar() |
23 | 24 | obj.sizeToFit() |
24 | 25 | obj.barTintColor = ColorConstants.lightGray |
25 | 26 | obj.clipsToBounds = true |
27 | + | |
26 | 28 | return obj |
27 | 29 | }() |
28 | 30 | |
... | ... | @@ -30,6 +32,7 @@ final class ToolbarView: UIView { |
30 | 32 | let obj = UIBarButtonItem() |
31 | 33 | obj.isEnabled = false |
32 | 34 | obj.image = UIImage(systemName: "chevron.backward") |
35 | + | |
33 | 36 | return obj |
34 | 37 | }() |
35 | 38 | |
... | ... | @@ -37,6 +40,7 @@ final class ToolbarView: UIView { |
37 | 40 | let obj = UIBarButtonItem() |
38 | 41 | obj.isEnabled = false |
39 | 42 | obj.image = UIImage(systemName: "chevron.forward") |
43 | + | |
40 | 44 | return obj |
41 | 45 | }() |
42 | 46 | |
... | ... | @@ -44,23 +48,27 @@ final class ToolbarView: UIView { |
44 | 48 | let obj = UIBarButtonItem() |
45 | 49 | obj.isEnabled = false |
46 | 50 | obj.image = UIImage(systemName: "square.and.arrow.up") |
51 | + | |
47 | 52 | return obj |
48 | 53 | }() |
49 | 54 | |
50 | - let historyBarButtonItem: UIBarButtonItem = { | |
55 | + private let historyBarButtonItem: UIBarButtonItem = { | |
51 | 56 | let obj = UIBarButtonItem() |
52 | 57 | obj.image = UIImage(systemName: "book") |
58 | + | |
53 | 59 | return obj |
54 | 60 | }() |
55 | 61 | |
56 | - let tabsBarButtonItem: UIBarButtonItem = { | |
62 | + private let tabsBarButtonItem: UIBarButtonItem = { | |
57 | 63 | let obj = UIBarButtonItem() |
58 | 64 | obj.image = UIImage(systemName: "square.on.square") |
65 | + | |
59 | 66 | return obj |
60 | 67 | }() |
61 | 68 | |
62 | 69 | override init(frame: CGRect) { |
63 | 70 | super.init(frame: frame) |
71 | + | |
64 | 72 | setup() |
65 | 73 | } |
66 | 74 | |
... | ... | @@ -70,18 +78,8 @@ final class ToolbarView: UIView { |
70 | 78 | |
71 | 79 | private func setup() { |
72 | 80 | addSubview(toolbar) |
73 | - let flexibleSpace = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil) | |
74 | - toolbar.items = [ | |
75 | - backBarButtonItem, | |
76 | - flexibleSpace, | |
77 | - forwardBarButtonItem, | |
78 | - flexibleSpace, | |
79 | - shareBarButtonItem, | |
80 | - flexibleSpace, | |
81 | - historyBarButtonItem, | |
82 | - flexibleSpace, | |
83 | - tabsBarButtonItem, | |
84 | - ] | |
81 | + | |
82 | + setupToolbar() | |
85 | 83 | initActions() |
86 | 84 | setupConstraints() |
87 | 85 | } |
... | ... | @@ -100,15 +98,34 @@ extension ToolbarView { |
100 | 98 | private func initActions() { |
101 | 99 | backBarButtonItem.action = #selector(didItemTapped(_:)) |
102 | 100 | backBarButtonItem.target = self |
101 | + | |
103 | 102 | forwardBarButtonItem.action = #selector(didItemTapped(_:)) |
104 | 103 | forwardBarButtonItem.target = self |
104 | + | |
105 | 105 | shareBarButtonItem.action = #selector(didItemTapped(_:)) |
106 | 106 | shareBarButtonItem.target = self |
107 | + | |
107 | 108 | historyBarButtonItem.action = #selector(didItemTapped(_:)) |
108 | 109 | historyBarButtonItem.target = self |
110 | + | |
109 | 111 | tabsBarButtonItem.action = #selector(didItemTapped(_:)) |
110 | 112 | tabsBarButtonItem.target = self |
111 | 113 | } |
114 | + | |
115 | + private func setupToolbar() { | |
116 | + let flexibleSpace = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil) | |
117 | + toolbar.items = [ | |
118 | + backBarButtonItem, | |
119 | + flexibleSpace, | |
120 | + forwardBarButtonItem, | |
121 | + flexibleSpace, | |
122 | + shareBarButtonItem, | |
123 | + flexibleSpace, | |
124 | + historyBarButtonItem, | |
125 | + flexibleSpace, | |
126 | + tabsBarButtonItem, | |
127 | + ] | |
128 | + } | |
112 | 129 | } |
113 | 130 | |
114 | 131 | // MARK: - Actions | ... | ... |
... | ... | @@ -4,23 +4,26 @@ |
4 | 4 | // |
5 | 5 | // Created by Artem Talko on 25.09.2023. |
6 | 6 | // |
7 | +//MARK: Checked | |
7 | 8 | |
8 | 9 | import UIKit |
9 | 10 | |
10 | 11 | final class PayloadViewController: UIViewController { |
11 | 12 | private let mainView = PayloadView() |
12 | - private let data = StringConstants.payloadViewControllerData | |
13 | + private let payloadTableViewData: [String] | |
13 | 14 | |
14 | 15 | override func viewDidLoad() { |
15 | 16 | super.viewDidLoad() |
16 | 17 | view.backgroundColor = ColorConstants.lightGray |
18 | + | |
17 | 19 | initViewController() |
18 | 20 | } |
19 | 21 | |
20 | 22 | private func initViewController() { |
23 | + navigationController?.isNavigationBarHidden = true | |
24 | + | |
21 | 25 | setupTableView() |
22 | 26 | addTargets() |
23 | - navigationController?.isNavigationBarHidden = true | |
24 | 27 | } |
25 | 28 | |
26 | 29 | override func loadView() { |
... | ... | @@ -28,37 +31,36 @@ final class PayloadViewController: UIViewController { |
28 | 31 | } |
29 | 32 | |
30 | 33 | init(){ |
34 | + payloadTableViewData = StringConstants.payloadViewControllerData | |
35 | + | |
31 | 36 | super.init(nibName: nil, bundle: nil) |
32 | 37 | } |
38 | + | |
33 | 39 | required init?(coder: NSCoder) { |
34 | 40 | fatalError("init(coder:) has not been implemented") |
35 | 41 | } |
36 | 42 | |
37 | 43 | override func viewWillDisappear(_ animated: Bool) { |
38 | 44 | super.viewWillDisappear(animated) |
45 | + | |
39 | 46 | NotificationCenter.default.removeObserver(self) |
40 | 47 | } |
41 | 48 | } |
42 | 49 | |
43 | 50 | extension PayloadViewController: UITableViewDelegate, UITableViewDataSource { |
44 | 51 | func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { |
45 | - return data.count | |
52 | + return payloadTableViewData.count | |
46 | 53 | } |
47 | 54 | |
48 | 55 | func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { |
49 | - guard let cell = tableView.dequeueReusableCell(withIdentifier: "AdvantagesTableViewCell") as? | |
56 | + guard let cell = tableView.dequeueReusableCell(withIdentifier: AdvantagesTableViewCell.cellID) as? | |
50 | 57 | AdvantagesTableViewCell else { |
51 | - return UITableViewCell() } | |
52 | - cell.advantagesCellLabel.text = data[indexPath.row] | |
53 | - cell.selectionStyle = .none | |
58 | + return UITableViewCell() | |
59 | + } | |
60 | + cell.advantagesCellLabel.text = payloadTableViewData[indexPath.row] | |
61 | + | |
54 | 62 | return cell |
55 | 63 | } |
56 | - | |
57 | - private func setupTableView() { | |
58 | - mainView.advantagesTableView.dataSource = self | |
59 | - mainView.advantagesTableView.delegate = self | |
60 | - mainView.advantagesTableView.register(AdvantagesTableViewCell.self, forCellReuseIdentifier: StringConstants.advantagesTableViewCell) | |
61 | - } | |
62 | 64 | } |
63 | 65 | |
64 | 66 | |
... | ... | @@ -73,9 +75,13 @@ extension PayloadViewController { |
73 | 75 | private func textPressed(_ sender: UITapGestureRecognizer) { |
74 | 76 | let termsViewController = TermsViewController() |
75 | 77 | termsViewController.modalPresentationStyle = .fullScreen |
78 | + | |
76 | 79 | present(termsViewController, animated: true) |
77 | 80 | } |
78 | - | |
81 | +} | |
82 | + | |
83 | +//MARK: Helpers | |
84 | +extension PayloadViewController { | |
79 | 85 | private func addTargets() { |
80 | 86 | mainView.getStartedButton.addTarget(self, action: #selector(getStartedButtonTapped(_ :)), for: .touchUpInside) |
81 | 87 | mainView.privacyLabelView.isUserInteractionEnabled = true |
... | ... | @@ -88,6 +94,11 @@ extension PayloadViewController { |
88 | 94 | let tapGesture = UITapGestureRecognizer(target: self, action: #selector(textPressed(_ :))) |
89 | 95 | mainView.infoLabel.addGestureRecognizer(tapGesture) |
90 | 96 | } |
97 | + | |
98 | + private func setupTableView() { | |
99 | + mainView.advantagesTableView.dataSource = self | |
100 | + mainView.advantagesTableView.delegate = self | |
101 | + mainView.advantagesTableView.register(AdvantagesTableViewCell.self, forCellReuseIdentifier: AdvantagesTableViewCell.cellID) | |
102 | + } | |
91 | 103 | } |
92 | 104 | |
93 | - | ... | ... |
... | ... | @@ -4,54 +4,59 @@ |
4 | 4 | // |
5 | 5 | // Created by Artem Talko on 26.09.2023. |
6 | 6 | // |
7 | +//MARK: Checked | |
7 | 8 | |
8 | 9 | import UIKit |
9 | 10 | |
10 | 11 | final class AdvantagesTableViewCell: UITableViewCell { |
12 | + static let cellID = String(describing: AdvantagesTableViewCell.self) | |
13 | + | |
11 | 14 | let advantagesCellLabel: UILabel = { |
12 | 15 | let obj = UILabel() |
13 | 16 | obj.font = FontConstants.semiboldFont_14 |
17 | + | |
14 | 18 | return obj |
15 | 19 | }() |
16 | 20 | |
17 | - let advantagesCellImage: UIImageView = { | |
21 | + private let advantagesCellImage: UIImageView = { | |
18 | 22 | let obj = UIImageView() |
19 | 23 | let checkmarkImg = UIImage(systemName: "checkmark")?.withTintColor(.blue, renderingMode: .alwaysOriginal) |
20 | 24 | obj.image = checkmarkImg |
21 | 25 | obj.contentMode = .scaleToFill |
26 | + | |
22 | 27 | return obj |
23 | 28 | }() |
24 | 29 | |
25 | 30 | override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { |
26 | 31 | super.init(style: style, reuseIdentifier: reuseIdentifier) |
27 | - setup() | |
28 | 32 | |
33 | + setup() | |
29 | 34 | } |
30 | 35 | |
31 | 36 | required init?(coder: NSCoder) { |
32 | 37 | fatalError("init(coder:) has not been implemented") |
33 | 38 | } |
34 | 39 | |
35 | - | |
36 | - | |
37 | - func setup() { | |
40 | + private func setup() { | |
41 | + selectionStyle = .none | |
42 | + backgroundColor = .clear | |
38 | 43 | contentView.addSubview(advantagesCellLabel) |
39 | 44 | contentView.addSubview(advantagesCellImage) |
45 | + | |
40 | 46 | setupConstraints() |
41 | - backgroundColor = .clear | |
42 | 47 | } |
43 | 48 | |
44 | 49 | private func setupConstraints() { |
45 | 50 | advantagesCellImage.snp.makeConstraints { make in |
46 | 51 | make.top.equalToSuperview().inset(5.sizeH) |
47 | - make.bottom.equalToSuperview().inset(5.sizeH) | |
48 | 52 | make.leading.equalToSuperview() |
53 | + make.bottom.equalToSuperview().inset(5.sizeH) | |
49 | 54 | make.trailing.equalTo(advantagesCellLabel.snp.leading).offset(-8.sizeW) |
50 | 55 | } |
51 | 56 | advantagesCellLabel.snp.makeConstraints { make in |
52 | 57 | make.top.equalToSuperview().inset(5.sizeH) |
53 | - make.bottom.equalToSuperview().inset(5.sizeH) | |
54 | 58 | make.leading.equalTo(advantagesCellImage.snp.trailing) |
59 | + make.bottom.equalToSuperview().inset(5.sizeH) | |
55 | 60 | make.trailing.equalToSuperview() |
56 | 61 | } |
57 | 62 | } | ... | ... |
... | ... | @@ -4,29 +4,32 @@ |
4 | 4 | // |
5 | 5 | // Created by Artem Talko on 25.09.2023. |
6 | 6 | // |
7 | +//MARK: Checked | |
7 | 8 | |
8 | 9 | import UIKit |
9 | 10 | |
10 | 11 | final class PayloadView: UIView { |
11 | - | |
12 | - let logoImageView: UIImageView = { | |
12 | + private let logoImageView: UIImageView = { | |
13 | 13 | let obj = UIImageView() |
14 | 14 | obj.image = UIImage(named: "Gotoweb") |
15 | 15 | obj.contentMode = .scaleAspectFit |
16 | + | |
16 | 17 | return obj |
17 | 18 | }() |
18 | 19 | |
19 | - let phoneImageView: UIImageView = { | |
20 | + private let phoneImageView: UIImageView = { | |
20 | 21 | let obj = UIImageView() |
21 | 22 | obj.image = UIImage(named: "Phone") |
22 | 23 | obj.contentMode = .scaleAspectFit |
24 | + | |
23 | 25 | return obj |
24 | 26 | }() |
25 | 27 | |
26 | - let zoomedTabImageView: UIImageView = { | |
28 | + private let zoomedTabImageView: UIImageView = { | |
27 | 29 | let obj = UIImageView() |
28 | 30 | obj.image = UIImage(named: "ZoomedTab") |
29 | 31 | obj.contentMode = .scaleAspectFit |
32 | + | |
30 | 33 | return obj |
31 | 34 | }() |
32 | 35 | |
... | ... | @@ -35,6 +38,7 @@ final class PayloadView: UIView { |
35 | 38 | obj.text = StringConstants.ourBrowser |
36 | 39 | obj.font = FontConstants.regularFont_12 |
37 | 40 | obj.numberOfLines = 0 |
41 | + | |
38 | 42 | return obj |
39 | 43 | }() |
40 | 44 | |
... | ... | @@ -43,10 +47,11 @@ final class PayloadView: UIView { |
43 | 47 | obj.backgroundColor = .clear |
44 | 48 | obj.isScrollEnabled = false |
45 | 49 | obj.separatorStyle = .none |
50 | + | |
46 | 51 | return obj |
47 | 52 | }() |
48 | 53 | |
49 | - let gradientLayer = CAGradientLayer() | |
54 | + private let gradientLayer = CAGradientLayer() | |
50 | 55 | |
51 | 56 | let getStartedButton: UIButton = { |
52 | 57 | let obj = UIButton() |
... | ... | @@ -55,6 +60,7 @@ final class PayloadView: UIView { |
55 | 60 | obj.setTitleColor(.white, for: .normal) |
56 | 61 | obj.layer.cornerRadius = 10 |
57 | 62 | obj.layer.masksToBounds = true |
63 | + | |
58 | 64 | return obj |
59 | 65 | }() |
60 | 66 | |
... | ... | @@ -64,17 +70,20 @@ final class PayloadView: UIView { |
64 | 70 | |
65 | 71 | let fullText = "By starting, you agree to our Terms and Condition and Privacy Policy." |
66 | 72 | let attributedText = NSMutableAttributedString(string: fullText) |
73 | + | |
67 | 74 | attributedText.addAttribute(.foregroundColor, value: UIColor(red: 0.349, green: 0.565, blue: 1, alpha: 1).cgColor, range: NSRange(location: fullText.range(of: "Terms and Condition")?.lowerBound.utf16Offset(in: fullText) ?? 0, length: "Terms and Condition".count)) |
68 | 75 | attributedText.addAttribute(.foregroundColor, value: UIColor(red: 0.349, green: 0.565, blue: 1, alpha: 1).cgColor, range: NSRange(location: fullText.range(of: "Privacy Policy")?.lowerBound.utf16Offset(in: fullText) ?? 0, length: "Privacy Policy".count)) |
69 | 76 | obj.attributedText = attributedText |
70 | 77 | obj.font = FontConstants.regularFont_12 |
71 | 78 | obj.numberOfLines = 0 |
72 | 79 | obj.isUserInteractionEnabled = true |
80 | + | |
73 | 81 | return obj |
74 | 82 | }() |
75 | 83 | |
76 | 84 | override init (frame: CGRect) { |
77 | 85 | super.init(frame: frame) |
86 | + | |
78 | 87 | setup() |
79 | 88 | } |
80 | 89 | |
... | ... | @@ -84,6 +93,7 @@ final class PayloadView: UIView { |
84 | 93 | |
85 | 94 | override func layoutSubviews() { |
86 | 95 | super.layoutSubviews() |
96 | + | |
87 | 97 | gradientLayer.frame = getStartedButton.bounds |
88 | 98 | } |
89 | 99 | |
... | ... | @@ -95,11 +105,12 @@ final class PayloadView: UIView { |
95 | 105 | addSubview(advantagesTableView) |
96 | 106 | addSubview(getStartedButton) |
97 | 107 | addSubview(privacyLabelView) |
108 | + | |
98 | 109 | setupConstraints() |
99 | 110 | gradientSetup() |
100 | 111 | } |
101 | 112 | |
102 | - func setupConstraints() { | |
113 | + private func setupConstraints() { | |
103 | 114 | logoImageView.snp.makeConstraints { make in |
104 | 115 | make.top.equalTo(safeAreaLayoutGuide.snp.top).offset(16.sizeH) |
105 | 116 | make.leading.trailing.equalToSuperview().inset(143.sizeW) |
... | ... | @@ -115,8 +126,8 @@ final class PayloadView: UIView { |
115 | 126 | zoomedTabImageView.snp.makeConstraints { make in |
116 | 127 | make.top.equalTo(phoneImageView.snp.top).offset(119.sizeH) |
117 | 128 | make.leading.equalTo(phoneImageView.snp.leading).offset(91.sizeW) |
118 | - make.trailing.equalToSuperview().offset(-71) | |
119 | 129 | make.bottom.equalTo(phoneImageView.snp.bottom).offset(-104.sizeH) |
130 | + make.trailing.equalToSuperview().offset(-71) | |
120 | 131 | } |
121 | 132 | |
122 | 133 | infoLabel.snp.makeConstraints { make in |
... | ... | @@ -127,8 +138,8 @@ final class PayloadView: UIView { |
127 | 138 | advantagesTableView.snp.makeConstraints { make in |
128 | 139 | make.top.equalTo(infoLabel.snp.bottom).offset(16.sizeH) |
129 | 140 | make.leading.equalToSuperview().offset(55.sizeW) |
130 | - make.trailing.equalToSuperview().offset(-92.sizeW) | |
131 | 141 | make.bottom.equalTo(getStartedButton.snp.top).offset(-38.sizeH) |
142 | + make.trailing.equalToSuperview().offset(-92.sizeW) | |
132 | 143 | } |
133 | 144 | |
134 | 145 | getStartedButton.snp.makeConstraints { make in | ... | ... |
... | ... | @@ -4,21 +4,23 @@ |
4 | 4 | // |
5 | 5 | // Created by Artem Talko on 27.09.2023. |
6 | 6 | // |
7 | +//MARK: Checked | |
7 | 8 | |
8 | 9 | import UIKit |
9 | 10 | |
10 | 11 | final class RemoveAdvertViewController: UIViewController { |
11 | - | |
12 | 12 | private let mainView = RemoveAdvertView() |
13 | - let data = StringConstants.removeAdvertTableViewData | |
13 | + private let removeTableViewCellsData: [String] | |
14 | 14 | |
15 | 15 | override func viewDidLoad() { |
16 | 16 | super.viewDidLoad() |
17 | - view.backgroundColor = ColorConstants.lightGray | |
17 | + | |
18 | 18 | initViewController() |
19 | 19 | } |
20 | 20 | |
21 | 21 | private func initViewController() { |
22 | + view.backgroundColor = ColorConstants.lightGray | |
23 | + | |
22 | 24 | setupTableView() |
23 | 25 | addTargets() |
24 | 26 | } |
... | ... | @@ -27,7 +29,9 @@ final class RemoveAdvertViewController: UIViewController { |
27 | 29 | view = mainView |
28 | 30 | } |
29 | 31 | |
30 | - init(){ | |
32 | + init() { | |
33 | + removeTableViewCellsData = StringConstants.removeAdvertTableViewData | |
34 | + | |
31 | 35 | super.init(nibName: nil, bundle: nil) |
32 | 36 | } |
33 | 37 | |
... | ... | @@ -40,35 +44,25 @@ final class RemoveAdvertViewController: UIViewController { |
40 | 44 | //MARK: - Table View |
41 | 45 | extension RemoveAdvertViewController: UITableViewDelegate, UITableViewDataSource { |
42 | 46 | func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { |
43 | - return data.count | |
47 | + return removeTableViewCellsData.count | |
44 | 48 | } |
45 | 49 | |
46 | 50 | func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { |
47 | - guard let cell = tableView.dequeueReusableCell(withIdentifier: "RemoveAdvertTableViewCell") as? | |
51 | + guard let cell = tableView.dequeueReusableCell(withIdentifier: RemoveAdvertTableViewCell.cellID) as? | |
48 | 52 | RemoveAdvertTableViewCell else { |
49 | - return UITableViewCell() } | |
50 | - | |
51 | - cell.advantagesCellLabel.text = data[indexPath.row] | |
53 | + return UITableViewCell() | |
54 | + } | |
55 | + | |
56 | + cell.advantagesCellLabel.text = removeTableViewCellsData[indexPath.row] | |
52 | 57 | cell.selectionStyle = .none |
53 | 58 | |
54 | 59 | return cell |
55 | 60 | } |
56 | - | |
57 | - private func setupTableView() { | |
58 | - mainView.advantagesTableView.dataSource = self | |
59 | - mainView.advantagesTableView.delegate = self | |
60 | - mainView.advantagesTableView.register(RemoveAdvertTableViewCell.self, forCellReuseIdentifier: StringConstants.removeAdvertTableViewCell) | |
61 | - } | |
62 | 61 | } |
63 | 62 | |
64 | 63 | |
65 | 64 | //MARK: - Action |
66 | 65 | extension RemoveAdvertViewController { |
67 | - private func addTargets() { | |
68 | - mainView.shieldView.addTarget(self, action: #selector(shieldButtonTapped(_ :)), for: .touchUpInside) | |
69 | - mainView.closeButton.addTarget(self, action: #selector(closeViewController(_ :)), for: .touchUpInside) | |
70 | - } | |
71 | - | |
72 | 66 | @objc |
73 | 67 | private func shieldButtonTapped(_ sender: UIButton) { |
74 | 68 | UIView.animate(withDuration: 0.2) { |
... | ... | @@ -76,6 +70,7 @@ extension RemoveAdvertViewController { |
76 | 70 | sender.alpha = 0.7 |
77 | 71 | } |
78 | 72 | let userDefaultsAdBlockerValue = CachingManager.shared.isAdBlocking |
73 | + | |
79 | 74 | if userDefaultsAdBlockerValue { |
80 | 75 | mainView.shieldView.setImage(.shieldInactive, for: .normal) |
81 | 76 | mainView.tapActionLabel.text = StringConstants.turnOff |
... | ... | @@ -96,3 +91,17 @@ extension RemoveAdvertViewController { |
96 | 91 | dismiss(animated: true, completion: nil) |
97 | 92 | } |
98 | 93 | } |
94 | + | |
95 | +//MARK: Helpers | |
96 | +extension RemoveAdvertViewController { | |
97 | + private func addTargets() { | |
98 | + mainView.shieldView.addTarget(self, action: #selector(shieldButtonTapped(_ :)), for: .touchUpInside) | |
99 | + mainView.closeButton.addTarget(self, action: #selector(closeViewController(_ :)), for: .touchUpInside) | |
100 | + } | |
101 | + | |
102 | + private func setupTableView() { | |
103 | + mainView.advantagesTableView.dataSource = self | |
104 | + mainView.advantagesTableView.delegate = self | |
105 | + mainView.advantagesTableView.register(RemoveAdvertTableViewCell.self, forCellReuseIdentifier: RemoveAdvertTableViewCell.cellID) | |
106 | + } | |
107 | +} | ... | ... |
... | ... | @@ -4,53 +4,58 @@ |
4 | 4 | // |
5 | 5 | // Created by Artem Talko on 01.10.2023. |
6 | 6 | // |
7 | +//MARK: Checked | |
7 | 8 | |
8 | 9 | import UIKit |
9 | 10 | |
10 | - | |
11 | 11 | final class RemoveAdvertTableViewCell: UITableViewCell { |
12 | + static let cellID = String(describing: RemoveAdvertTableViewCell.self) | |
13 | + | |
12 | 14 | let advantagesCellLabel: UILabel = { |
13 | 15 | let obj = UILabel() |
14 | 16 | obj.font = FontConstants.regularFont_14 |
17 | + | |
15 | 18 | return obj |
16 | 19 | }() |
17 | 20 | |
18 | - let advantagesCellImage: UIImageView = { | |
21 | + private let advantagesCellImage: UIImageView = { | |
19 | 22 | let obj = UIImageView() |
20 | 23 | let checkmarkImg = UIImage(systemName: "checkmark")?.withTintColor(.blue, renderingMode: .alwaysOriginal) |
21 | 24 | obj.image = checkmarkImg |
22 | 25 | obj.contentMode = .scaleToFill |
26 | + | |
23 | 27 | return obj |
24 | 28 | }() |
25 | 29 | |
26 | 30 | override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { |
27 | 31 | super.init(style: style, reuseIdentifier: reuseIdentifier) |
28 | - setup() | |
29 | 32 | |
33 | + setup() | |
30 | 34 | } |
31 | 35 | |
32 | 36 | required init?(coder: NSCoder) { |
33 | 37 | fatalError("init(coder:) has not been implemented") |
34 | 38 | } |
35 | 39 | |
36 | - func setup() { | |
40 | + private func setup() { | |
41 | + backgroundColor = .clear | |
37 | 42 | contentView.addSubview(advantagesCellLabel) |
38 | 43 | contentView.addSubview(advantagesCellImage) |
39 | - backgroundColor = .clear | |
44 | + | |
40 | 45 | setupConstraints() |
41 | 46 | } |
42 | 47 | |
43 | 48 | private func setupConstraints() { |
44 | 49 | advantagesCellImage.snp.makeConstraints { make in |
45 | 50 | make.top.equalToSuperview().inset(5.sizeH) |
46 | - make.bottom.equalToSuperview().inset(5.sizeH) | |
47 | 51 | make.leading.equalToSuperview() |
52 | + make.bottom.equalToSuperview().inset(5.sizeH) | |
48 | 53 | make.trailing.equalTo(advantagesCellLabel.snp.leading).offset(-8.sizeW) |
49 | 54 | } |
50 | 55 | advantagesCellLabel.snp.makeConstraints { make in |
51 | 56 | make.top.equalToSuperview().inset(5.sizeH) |
52 | - make.bottom.equalToSuperview().inset(5.sizeH) | |
53 | 57 | make.leading.equalTo(advantagesCellImage.snp.trailing) |
58 | + make.bottom.equalToSuperview().inset(5.sizeH) | |
54 | 59 | make.trailing.equalToSuperview() |
55 | 60 | } |
56 | 61 | } | ... | ... |
... | ... | @@ -4,17 +4,18 @@ |
4 | 4 | // |
5 | 5 | // Created by Artem Talko on 29.09.2023. |
6 | 6 | // |
7 | +//MARK: Checked | |
7 | 8 | |
8 | 9 | import UIKit |
9 | 10 | import SnapKit |
10 | 11 | |
11 | 12 | final class RemoveAdvertView: UIView { |
12 | - | |
13 | 13 | let closeButton: UIButton = { |
14 | 14 | let obj = UIButton() |
15 | 15 | obj.setImage(UIImage(systemName: "xmark"), for: .normal) |
16 | 16 | obj.contentMode = .scaleToFill |
17 | 17 | obj.tintColor = .gray |
18 | + | |
18 | 19 | return obj |
19 | 20 | }() |
20 | 21 | |
... | ... | @@ -24,22 +25,21 @@ final class RemoveAdvertView: UIView { |
24 | 25 | |
25 | 26 | if userDefaultsValue { |
26 | 27 | obj.setImage(UIImage(named: "ShieldActive"), for: .normal) |
27 | - print(userDefaultsValue) | |
28 | 28 | } else { |
29 | 29 | obj.setImage(UIImage(named: "ShieldInactive"), for: .normal) |
30 | - print(userDefaultsValue) | |
31 | 30 | } |
32 | - | |
33 | 31 | obj.contentMode = .scaleAspectFit |
32 | + | |
34 | 33 | return obj |
35 | 34 | }() |
36 | 35 | |
37 | - let gradientLayer = CAGradientLayer() | |
36 | + private let gradientLayer = CAGradientLayer() | |
38 | 37 | |
39 | - let abvertBlockerModeLabel: UILabel = { | |
38 | + private let abvertBlockerModeLabel: UILabel = { | |
40 | 39 | let obj = UILabel() |
41 | 40 | obj.text = StringConstants.advertMode |
42 | 41 | obj.font = FontConstants.semiboldFont_18 |
42 | + | |
43 | 43 | return obj |
44 | 44 | }() |
45 | 45 | |
... | ... | @@ -47,6 +47,7 @@ final class RemoveAdvertView: UIView { |
47 | 47 | let obj = UILabel() |
48 | 48 | obj.text = StringConstants.turnOff |
49 | 49 | obj.font = FontConstants.semiboldFont_14 |
50 | + | |
50 | 51 | return obj |
51 | 52 | }() |
52 | 53 | |
... | ... | @@ -55,24 +56,27 @@ final class RemoveAdvertView: UIView { |
55 | 56 | obj.backgroundColor = .clear |
56 | 57 | obj.isScrollEnabled = false |
57 | 58 | obj.separatorStyle = .none |
59 | + | |
58 | 60 | return obj |
59 | 61 | }() |
60 | 62 | |
61 | - let claimOfferLabel: UILabel = { | |
63 | + private let claimOfferLabel: UILabel = { | |
62 | 64 | let obj = UILabel() |
63 | 65 | obj.text = StringConstants.claimOffer |
64 | 66 | obj.font = FontConstants.regularFont_12 |
67 | + | |
65 | 68 | return obj |
66 | 69 | }() |
67 | 70 | |
68 | - let priceLabel: UILabel = { | |
71 | + private let priceLabel: UILabel = { | |
69 | 72 | let obj = UILabel() |
70 | 73 | obj.text = StringConstants.price |
71 | 74 | obj.font = FontConstants.regularFont_18 |
75 | + | |
72 | 76 | return obj |
73 | 77 | }() |
74 | 78 | |
75 | - let subscribeButton: UIButton = { | |
79 | + private let subscribeButton: UIButton = { | |
76 | 80 | let obj = UIButton() |
77 | 81 | obj.backgroundColor = .systemIndigo |
78 | 82 | obj.setTitle(StringConstants.subscribe, for: .normal) |
... | ... | @@ -80,32 +84,37 @@ final class RemoveAdvertView: UIView { |
80 | 84 | obj.setTitleColor(.white, for: .normal) |
81 | 85 | obj.layer.cornerRadius = 10 |
82 | 86 | obj.layer.masksToBounds = true |
87 | + | |
83 | 88 | return obj |
84 | 89 | }() |
85 | 90 | |
86 | - let freeTrialLabel: UILabel = { | |
91 | + private let freeTrialLabel: UILabel = { | |
87 | 92 | let obj = UILabel() |
88 | 93 | obj.textAlignment = .center |
89 | 94 | obj.font = FontConstants.semiboldFont_12 |
90 | 95 | obj.text = StringConstants.freeTrial |
96 | + | |
91 | 97 | return obj |
92 | 98 | }() |
93 | 99 | |
94 | - let discountLabel: UILabel = { | |
100 | + private let discountLabel: UILabel = { | |
95 | 101 | let obj = UILabel() |
96 | 102 | obj.textAlignment = .center |
97 | 103 | obj.text = StringConstants.yourDiscount |
98 | 104 | obj.font = FontConstants.regularFont_12 |
105 | + | |
99 | 106 | return obj |
100 | 107 | }() |
101 | 108 | |
102 | 109 | override init (frame: CGRect) { |
103 | 110 | super.init(frame: frame) |
111 | + | |
104 | 112 | setup() |
105 | 113 | } |
106 | 114 | |
107 | 115 | override func layoutSubviews() { |
108 | 116 | super.layoutSubviews() |
117 | + | |
109 | 118 | gradientLayer.frame = subscribeButton.bounds |
110 | 119 | } |
111 | 120 | |
... | ... | @@ -124,61 +133,70 @@ final class RemoveAdvertView: UIView { |
124 | 133 | addSubview(subscribeButton) |
125 | 134 | addSubview(freeTrialLabel) |
126 | 135 | addSubview(discountLabel) |
136 | + | |
127 | 137 | setupConstraints() |
128 | 138 | gradientSetup() |
129 | 139 | } |
130 | 140 | |
131 | - func setupConstraints() { | |
141 | + private func setupConstraints() { | |
132 | 142 | closeButton.snp.makeConstraints { make in |
133 | 143 | make.top.equalTo(safeAreaLayoutGuide.snp.top).offset(16.sizeH) |
134 | - make.height.equalTo(24.sizeH) | |
135 | 144 | make.trailing.equalToSuperview().inset(16.sizeW) |
145 | + make.height.equalTo(24.sizeH) | |
136 | 146 | } |
137 | 147 | |
138 | 148 | shieldView.snp.makeConstraints { make in |
139 | 149 | make.top.equalTo(closeButton.snp.top).offset(8.sizeH) |
140 | - make.height.equalTo(280.sizeH) | |
141 | 150 | make.leading.trailing.equalToSuperview().inset(47.sizeW) |
151 | + make.height.equalTo(280.sizeH) | |
142 | 152 | } |
153 | + | |
143 | 154 | abvertBlockerModeLabel.snp.makeConstraints { make in |
144 | 155 | make.top.equalTo(shieldView.snp.bottom).offset(16.sizeH) |
145 | 156 | make.centerX.equalToSuperview() |
146 | 157 | } |
158 | + | |
147 | 159 | tapActionLabel.snp.makeConstraints { make in |
148 | 160 | make.top.equalTo(abvertBlockerModeLabel.snp.bottom).offset(8.sizeH) |
149 | 161 | make.centerX.equalToSuperview() |
150 | 162 | } |
163 | + | |
151 | 164 | advantagesTableView.snp.makeConstraints { make in |
152 | 165 | make.top.equalTo(tapActionLabel.snp.bottom).offset(26.sizeH) |
153 | - make.bottom.equalTo(claimOfferLabel.snp.top).offset(-24.sizeH) | |
154 | 166 | make.leading.equalToSuperview().offset(80.sizeW) |
167 | + make.bottom.equalTo(claimOfferLabel.snp.top).offset(-24.sizeH) | |
155 | 168 | make.trailing.equalToSuperview().offset(-86.sizeW) |
156 | 169 | } |
170 | + | |
157 | 171 | claimOfferLabel.snp.makeConstraints { make in |
158 | 172 | make.bottom.equalTo(priceLabel.snp.top).offset(-4.sizeH) |
159 | 173 | make.centerX.equalToSuperview() |
160 | 174 | } |
175 | + | |
161 | 176 | priceLabel.snp.makeConstraints { make in |
162 | 177 | make.bottom.equalTo(subscribeButton.snp.top).offset(-16.sizeH) |
163 | 178 | make.centerX.equalToSuperview() |
164 | 179 | } |
180 | + | |
165 | 181 | subscribeButton.snp.makeConstraints { make in |
166 | - make.bottom.equalTo(freeTrialLabel.snp.top).offset(-16.sizeH) | |
167 | 182 | make.leading.trailing.equalToSuperview().inset(32.sizeW) |
183 | + make.bottom.equalTo(freeTrialLabel.snp.top).offset(-16.sizeH) | |
168 | 184 | make.height.equalTo(40.sizeH) |
169 | 185 | } |
186 | + | |
170 | 187 | freeTrialLabel.snp.makeConstraints { make in |
171 | 188 | make.bottom.equalTo(discountLabel.snp.top).offset(-8.sizeH) |
172 | 189 | make.centerX.equalToSuperview() |
173 | 190 | } |
191 | + | |
174 | 192 | discountLabel.snp.makeConstraints { make in |
175 | - make.centerX.equalToSuperview() | |
176 | 193 | make.bottom.equalTo(safeAreaLayoutGuide.snp.bottom).offset(-24.sizeH) |
194 | + make.centerX.equalToSuperview() | |
177 | 195 | } |
178 | 196 | } |
179 | 197 | } |
180 | 198 | |
181 | -//MARK: gradient | |
199 | +//MARK: Gradient | |
182 | 200 | extension RemoveAdvertView { |
183 | 201 | private func gradientSetup() { |
184 | 202 | subscribeButton.layer.insertSublayer(gradientLayer, at: 0) | ... | ... |
... | ... | @@ -4,6 +4,7 @@ |
4 | 4 | // |
5 | 5 | // Created by Artem Talko on 05.10.2023. |
6 | 6 | // |
7 | +//MARK: Checked | |
7 | 8 | |
8 | 9 | import UIKit |
9 | 10 | import WebKit |
... | ... | @@ -14,6 +15,7 @@ final class SearchResultViewController: UIViewController { |
14 | 15 | |
15 | 16 | init(searchLink: String) { |
16 | 17 | self.searchLink = searchLink |
18 | + | |
17 | 19 | super.init(nibName: nil, bundle: nil) |
18 | 20 | } |
19 | 21 | |
... | ... | @@ -27,11 +29,13 @@ final class SearchResultViewController: UIViewController { |
27 | 29 | |
28 | 30 | override func viewDidLoad() { |
29 | 31 | super.viewDidLoad() |
32 | + | |
30 | 33 | initViewController() |
31 | 34 | } |
32 | 35 | |
33 | 36 | private func initViewController() { |
34 | 37 | view.backgroundColor = ColorConstants.lightGray |
38 | + | |
35 | 39 | urlChecker(searchLink) |
36 | 40 | setupAdBlocker() |
37 | 41 | } |
... | ... | @@ -42,7 +46,7 @@ final class SearchResultViewController: UIViewController { |
42 | 46 | } |
43 | 47 | |
44 | 48 | extension SearchResultViewController { |
45 | - func urlChecker(_ url: String) { | |
49 | + private func urlChecker(_ url: String) { | |
46 | 50 | let request = URLRequest(url: URL(string: url) ?? URL(fileURLWithPath: "")) |
47 | 51 | mainView.searchResultView.load(request) |
48 | 52 | } |
... | ... | @@ -51,7 +55,7 @@ extension SearchResultViewController { |
51 | 55 | |
52 | 56 | //MARK: AdBlocker |
53 | 57 | extension SearchResultViewController { |
54 | - func setupAdBlocker() { | |
58 | + private func setupAdBlocker() { | |
55 | 59 | let userDefaultsValue = CachingManager.shared.isAdBlocking |
56 | 60 | if userDefaultsValue { |
57 | 61 | WKContentRuleListStore.default().getAvailableContentRuleListIdentifiers { res in | ... | ... |
... | ... | @@ -4,7 +4,7 @@ |
4 | 4 | // |
5 | 5 | // Created by Artem Talko on 05.10.2023. |
6 | 6 | // |
7 | - | |
7 | +//MARK: Checked | |
8 | 8 | import UIKit |
9 | 9 | import WebKit |
10 | 10 | |
... | ... | @@ -18,6 +18,7 @@ final class SearchResultView: UIView { |
18 | 18 | |
19 | 19 | override init(frame: CGRect) { |
20 | 20 | super.init(frame: frame) |
21 | + | |
21 | 22 | setup() |
22 | 23 | } |
23 | 24 | |
... | ... | @@ -26,9 +27,10 @@ final class SearchResultView: UIView { |
26 | 27 | } |
27 | 28 | |
28 | 29 | private func setup() { |
30 | + backgroundColor = .white | |
31 | + | |
29 | 32 | addSubview(searchResultView) |
30 | 33 | setupConstaraints() |
31 | - backgroundColor = .white | |
32 | 34 | } |
33 | 35 | |
34 | 36 | private func setupConstaraints() { | ... | ... |
... | ... | @@ -4,12 +4,14 @@ |
4 | 4 | // |
5 | 5 | // Created by Artem Talko on 29.09.2023. |
6 | 6 | // |
7 | +//MARK: Checked | |
7 | 8 | |
8 | 9 | import UIKit |
9 | 10 | |
10 | 11 | final class SearchingViewController: UIViewController { |
11 | 12 | let mainView = SearchingView() |
12 | - var dataForReq: [String] { | |
13 | + | |
14 | + var searchRequestData: [String] { | |
13 | 15 | didSet { |
14 | 16 | mainView.searchTableView.reloadData() |
15 | 17 | } |
... | ... | @@ -17,7 +19,8 @@ final class SearchingViewController: UIViewController { |
17 | 19 | var searchCell: ((UITableViewCell) -> Void)? |
18 | 20 | |
19 | 21 | init(dataForReq: [String]) { |
20 | - self.dataForReq = dataForReq | |
22 | + self.searchRequestData = dataForReq | |
23 | + | |
21 | 24 | super.init(nibName: nil, bundle: nil) |
22 | 25 | } |
23 | 26 | |
... | ... | @@ -31,6 +34,7 @@ final class SearchingViewController: UIViewController { |
31 | 34 | |
32 | 35 | override func viewDidLoad() { |
33 | 36 | super.viewDidLoad() |
37 | + | |
34 | 38 | view.backgroundColor = ColorConstants.lightGray |
35 | 39 | initViewController() |
36 | 40 | } |
... | ... | @@ -40,16 +44,17 @@ final class SearchingViewController: UIViewController { |
40 | 44 | } |
41 | 45 | } |
42 | 46 | |
47 | +//MARK: Setup TableView | |
43 | 48 | extension SearchingViewController: UITableViewDelegate, UITableViewDataSource { |
44 | 49 | func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { |
45 | - return dataForReq.count | |
50 | + return searchRequestData.count | |
46 | 51 | } |
47 | 52 | |
48 | 53 | func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { |
49 | - guard let cell = tableView.dequeueReusableCell(withIdentifier: "SearchingTableViewCell", for: indexPath) as? SearchingTableViewCell else { | |
50 | - return SearchingTableViewCell() | |
54 | + guard let cell = tableView.dequeueReusableCell(withIdentifier: SearchingTableViewCell.cellID, for: indexPath) as? SearchingTableViewCell else { | |
55 | + return UITableViewCell() | |
51 | 56 | } |
52 | - let searchCellData = dataForReq[indexPath.row] | |
57 | + let searchCellData = searchRequestData[indexPath.row] | |
53 | 58 | cell.model = searchCellData |
54 | 59 | return cell |
55 | 60 | } |
... | ... | @@ -58,11 +63,15 @@ extension SearchingViewController: UITableViewDelegate, UITableViewDataSource { |
58 | 63 | guard let tappedCell = tableView.cellForRow(at: indexPath) else { return } |
59 | 64 | searchCell?(tappedCell) |
60 | 65 | } |
61 | - | |
62 | - func setupTableView() { | |
66 | +} | |
67 | + | |
68 | + | |
69 | +//MARK: Helper | |
70 | +extension SearchingViewController { | |
71 | + private func setupTableView() { | |
63 | 72 | mainView.searchTableView.dataSource = self |
64 | 73 | mainView.searchTableView.delegate = self |
65 | - mainView.searchTableView.register(SearchingTableViewCell.self, forCellReuseIdentifier: StringConstants.searchTableViewCell) | |
74 | + mainView.searchTableView.register(SearchingTableViewCell.self, forCellReuseIdentifier: SearchingTableViewCell.cellID) | |
66 | 75 | } |
67 | 76 | } |
68 | 77 | ... | ... |
... | ... | @@ -4,44 +4,52 @@ |
4 | 4 | // |
5 | 5 | // Created by Artem Talko on 29.09.2023. |
6 | 6 | // |
7 | +//MARK: Checked | |
7 | 8 | |
8 | 9 | import UIKit |
9 | 10 | |
10 | -class SearchingTableViewCell: UITableViewCell { | |
11 | +final class SearchingTableViewCell: UITableViewCell { | |
12 | + static let cellID = String(describing: SearchingTableViewCell.self) | |
13 | + | |
11 | 14 | var model: String? { |
12 | 15 | didSet { |
13 | 16 | handleUI() |
14 | 17 | } |
15 | 18 | } |
16 | 19 | |
17 | - var searchImage: UIImageView = { | |
20 | + private var searchImage: UIImageView = { | |
18 | 21 | let obj = UIImageView() |
19 | 22 | obj.image = UIImage(systemName: "magnifyingglass") |
20 | 23 | obj.tintColor = .gray |
24 | + | |
21 | 25 | return obj |
22 | 26 | }() |
23 | 27 | |
24 | 28 | var searchLabel: UILabel = { |
25 | 29 | let obj = UILabel() |
26 | 30 | obj.font = FontConstants.regularFont_14 |
31 | + | |
27 | 32 | return obj |
28 | 33 | }() |
29 | 34 | |
30 | - var siteLogoImage: UIImageView = { | |
35 | + private var siteLogoImage: UIImageView = { | |
31 | 36 | let obj = UIImageView() |
37 | + | |
32 | 38 | return obj |
33 | 39 | }() |
34 | 40 | |
35 | - var linkImage: UIImageView = { | |
41 | + private var linkImage: UIImageView = { | |
36 | 42 | let obj = UIImageView() |
37 | 43 | obj.image = UIImage(systemName: "arrow.up.left") |
38 | 44 | obj.tintColor = .gray |
45 | + | |
39 | 46 | return obj |
40 | 47 | }() |
41 | 48 | |
42 | 49 | |
43 | 50 | override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { |
44 | 51 | super.init(style: style, reuseIdentifier: reuseIdentifier) |
52 | + | |
45 | 53 | setup() |
46 | 54 | } |
47 | 55 | |
... | ... | @@ -49,7 +57,7 @@ class SearchingTableViewCell: UITableViewCell { |
49 | 57 | fatalError("init(coder:) has not been implemented") |
50 | 58 | } |
51 | 59 | |
52 | - func setup() { | |
60 | + private func setup() { | |
53 | 61 | contentView.addSubview(searchImage) |
54 | 62 | contentView.addSubview(searchLabel) |
55 | 63 | contentView.addSubview(siteLogoImage) | ... | ... |
... | ... | @@ -4,13 +4,14 @@ |
4 | 4 | // |
5 | 5 | // Created by Artem Talko on 29.09.2023. |
6 | 6 | // |
7 | - | |
7 | +//MARK: Checked | |
8 | 8 | import UIKit |
9 | 9 | |
10 | 10 | final class SearchingView: UIView, UITextFieldDelegate { |
11 | 11 | let searchingButton: UIButton = { |
12 | 12 | let obj = UIButton() |
13 | 13 | obj.setImage(UIImage(systemName: "arrow.left"), for: .normal) |
14 | + | |
14 | 15 | return obj |
15 | 16 | }() |
16 | 17 | |
... | ... | @@ -18,6 +19,7 @@ final class SearchingView: UIView, UITextFieldDelegate { |
18 | 19 | let obj = UILabel() |
19 | 20 | obj.text = "Searching" |
20 | 21 | obj.font = FontConstants.semiboldFont_18 |
22 | + | |
21 | 23 | return obj |
22 | 24 | }() |
23 | 25 | |
... | ... | @@ -25,11 +27,13 @@ final class SearchingView: UIView, UITextFieldDelegate { |
25 | 27 | let obj = UITableView() |
26 | 28 | obj.backgroundColor = .clear |
27 | 29 | obj.separatorStyle = .none |
30 | + | |
28 | 31 | return obj |
29 | 32 | }() |
30 | 33 | |
31 | 34 | override init(frame: CGRect) { |
32 | 35 | super.init(frame: frame) |
36 | + | |
33 | 37 | setup() |
34 | 38 | } |
35 | 39 | |
... | ... | @@ -38,11 +42,12 @@ final class SearchingView: UIView, UITextFieldDelegate { |
38 | 42 | } |
39 | 43 | |
40 | 44 | private func setup() { |
45 | + backgroundColor = .white | |
46 | + | |
41 | 47 | addSubview(searchingButton) |
42 | 48 | addSubview(searchingLabel) |
43 | 49 | addSubview(searchTableView) |
44 | 50 | setupConstaraints() |
45 | - backgroundColor = .white | |
46 | 51 | } |
47 | 52 | |
48 | 53 | private func setupConstaraints() { | ... | ... |
... | ... | @@ -12,6 +12,7 @@ final class PrivacyViewController: UIViewController { |
12 | 12 | |
13 | 13 | override func viewDidLoad() { |
14 | 14 | super.viewDidLoad() |
15 | + | |
15 | 16 | initViewController() |
16 | 17 | } |
17 | 18 | |
... | ... | @@ -19,14 +20,6 @@ final class PrivacyViewController: UIViewController { |
19 | 20 | view = mainView |
20 | 21 | } |
21 | 22 | |
22 | - init() { | |
23 | - super.init(nibName: nil, bundle: nil) | |
24 | - } | |
25 | - | |
26 | - required init?(coder: NSCoder) { | |
27 | - fatalError("init(coder:) has not been implemented") | |
28 | - } | |
29 | - | |
30 | 23 | private func initViewController() { |
31 | 24 | addTargets() |
32 | 25 | mainView.backgroundColor = .white |
... | ... | @@ -34,10 +27,9 @@ final class PrivacyViewController: UIViewController { |
34 | 27 | } |
35 | 28 | } |
36 | 29 | |
37 | - | |
38 | 30 | //MARK: Helper |
39 | 31 | extension PrivacyViewController { |
40 | - func addTargets() { | |
32 | + private func addTargets() { | |
41 | 33 | mainView.privacyButton.addTarget(self, action: #selector(privacyButtonPressed), for: .touchUpInside) |
42 | 34 | } |
43 | 35 | } |
... | ... | @@ -45,7 +37,7 @@ extension PrivacyViewController { |
45 | 37 | //MARK: Targets |
46 | 38 | extension PrivacyViewController { |
47 | 39 | @objc |
48 | - func privacyButtonPressed() { | |
40 | + private func privacyButtonPressed() { | |
49 | 41 | self.dismiss(animated: true) |
50 | 42 | } |
51 | 43 | } | ... | ... |
... | ... | @@ -4,10 +4,10 @@ |
4 | 4 | // |
5 | 5 | // Created by Artem Talko on 08.11.2023. |
6 | 6 | // |
7 | +//MARK: Checked | |
7 | 8 | |
8 | 9 | import UIKit |
9 | 10 | |
10 | - | |
11 | 11 | final class PrivacyView: UIView { |
12 | 12 | private let privacyHeaderLabel: UILabel = { |
13 | 13 | let obj = UILabel() |
... | ... | @@ -49,6 +49,7 @@ final class PrivacyView: UIView { |
49 | 49 | |
50 | 50 | override init(frame: CGRect) { |
51 | 51 | super.init(frame: frame) |
52 | + | |
52 | 53 | setup() |
53 | 54 | } |
54 | 55 | |
... | ... | @@ -57,11 +58,13 @@ final class PrivacyView: UIView { |
57 | 58 | } |
58 | 59 | |
59 | 60 | private func setup() { |
60 | - addSubview(privacyHeaderLabel) | |
61 | - addSubview(privacyButton) | |
62 | 61 | privacyStackView.addSubview(privacyMainInfoLabel) |
63 | 62 | privacyScrollView.addSubview(privacyStackView) |
63 | + | |
64 | + addSubview(privacyHeaderLabel) | |
65 | + addSubview(privacyButton) | |
64 | 66 | addSubview(privacyScrollView) |
67 | + | |
65 | 68 | setupConstraints() |
66 | 69 | } |
67 | 70 | ... | ... |
... | ... | @@ -4,6 +4,7 @@ |
4 | 4 | // |
5 | 5 | // Created by Artem Talko on 08.11.2023. |
6 | 6 | // |
7 | +//MARK: Checked | |
7 | 8 | |
8 | 9 | import UIKit |
9 | 10 | |
... | ... | @@ -12,6 +13,7 @@ final class TermsViewController: UIViewController { |
12 | 13 | |
13 | 14 | override func viewDidLoad() { |
14 | 15 | super.viewDidLoad() |
16 | + | |
15 | 17 | initViewController() |
16 | 18 | } |
17 | 19 | |
... | ... | @@ -19,25 +21,17 @@ final class TermsViewController: UIViewController { |
19 | 21 | view = mainView |
20 | 22 | } |
21 | 23 | |
22 | - init() { | |
23 | - super.init(nibName: nil, bundle: nil) | |
24 | - } | |
25 | - | |
26 | - required init?(coder: NSCoder) { | |
27 | - fatalError("init(coder:) has not been implemented") | |
28 | - } | |
29 | - | |
30 | 24 | private func initViewController() { |
31 | - addTargets() | |
32 | 25 | mainView.backgroundColor = .white |
33 | 26 | |
27 | + addTargets() | |
34 | 28 | } |
35 | 29 | } |
36 | 30 | |
37 | 31 | |
38 | 32 | //MARK: Helper |
39 | 33 | extension TermsViewController { |
40 | - func addTargets() { | |
34 | + private func addTargets() { | |
41 | 35 | mainView.termsButton.addTarget(self, action: #selector(privacyButtonPressed), for: .touchUpInside) |
42 | 36 | } |
43 | 37 | } |
... | ... | @@ -45,7 +39,7 @@ extension TermsViewController { |
45 | 39 | //MARK: Targets |
46 | 40 | extension TermsViewController { |
47 | 41 | @objc |
48 | - func privacyButtonPressed() { | |
42 | + private func privacyButtonPressed() { | |
49 | 43 | self.dismiss(animated: true) |
50 | 44 | } |
51 | 45 | } | ... | ... |
... | ... | @@ -4,6 +4,8 @@ |
4 | 4 | // |
5 | 5 | // Created by Artem Talko on 08.11.2023. |
6 | 6 | // |
7 | +//MARK: Checked | |
8 | + | |
7 | 9 | |
8 | 10 | import UIKit |
9 | 11 | |
... | ... | @@ -14,6 +16,7 @@ final class TermsView: UIView { |
14 | 16 | obj.numberOfLines = 0 |
15 | 17 | obj.textAlignment = .center |
16 | 18 | obj.font = FontConstants.semiboldFont_18 |
19 | + | |
17 | 20 | return obj |
18 | 21 | }() |
19 | 22 | |
... | ... | @@ -22,6 +25,7 @@ final class TermsView: UIView { |
22 | 25 | obj.text = StringConstants.settingTerms |
23 | 26 | obj.numberOfLines = 0 |
24 | 27 | obj.font = FontConstants.regularFont_18 |
28 | + | |
25 | 29 | return obj |
26 | 30 | }() |
27 | 31 | |
... | ... | @@ -31,23 +35,27 @@ final class TermsView: UIView { |
31 | 35 | obj.layer.cornerRadius = 10 |
32 | 36 | obj.setTitle(StringConstants.settingAgreeButtonText, for: .normal) |
33 | 37 | obj.setTitleColor(.black, for: .normal) |
38 | + | |
34 | 39 | return obj |
35 | 40 | }() |
36 | 41 | |
37 | 42 | private let termsStackView: UIStackView = { |
38 | 43 | let obj = UIStackView() |
39 | 44 | obj.axis = .vertical |
45 | + | |
40 | 46 | return obj |
41 | 47 | }() |
42 | 48 | |
43 | 49 | private let termsScrollView: UIScrollView = { |
44 | 50 | let obj = UIScrollView() |
45 | 51 | obj.showsVerticalScrollIndicator = false |
52 | + | |
46 | 53 | return obj |
47 | 54 | }() |
48 | 55 | |
49 | 56 | override init(frame: CGRect) { |
50 | 57 | super.init(frame: frame) |
58 | + | |
51 | 59 | setup() |
52 | 60 | } |
53 | 61 | |
... | ... | @@ -56,11 +64,13 @@ final class TermsView: UIView { |
56 | 64 | } |
57 | 65 | |
58 | 66 | private func setup() { |
59 | - addSubview(termsHeaderLabel) | |
60 | - addSubview(termsButton) | |
61 | 67 | termsStackView.addSubview(termsMainInfoLabel) |
62 | 68 | termsScrollView.addSubview(termsStackView) |
69 | + | |
70 | + addSubview(termsHeaderLabel) | |
71 | + addSubview(termsButton) | |
63 | 72 | addSubview(termsScrollView) |
73 | + | |
64 | 74 | setupConstraints() |
65 | 75 | } |
66 | 76 | ... | ... |
... | ... | @@ -4,27 +4,29 @@ |
4 | 4 | // |
5 | 5 | // Created by Artem Talko on 28.09.2023. |
6 | 6 | // |
7 | +//MARK: Checked | |
7 | 8 | |
8 | 9 | import UIKit |
9 | 10 | import RealmSwift |
10 | 11 | import Realm |
11 | 12 | |
12 | - | |
13 | - | |
14 | 13 | final class TabsViewController: UIViewController { |
15 | 14 | private var tabsData: [BrowserTabDataBase] = [] |
15 | + | |
16 | 16 | var cellIndexPathForTransition: IndexPath? |
17 | 17 | let mainView = TabsView() |
18 | 18 | |
19 | 19 | override func viewDidLoad() { |
20 | 20 | super.viewDidLoad() |
21 | + | |
21 | 22 | initViewController() |
22 | 23 | } |
23 | 24 | |
24 | 25 | private func initViewController() { |
26 | + view.backgroundColor = UIColor(red: 0.984, green: 0.984, blue: 0.984, alpha: 1) | |
27 | + | |
25 | 28 | setupCollectionView() |
26 | 29 | addTargets() |
27 | - view.backgroundColor = UIColor(red: 0.984, green: 0.984, blue: 0.984, alpha: 1) | |
28 | 30 | } |
29 | 31 | |
30 | 32 | override func viewWillAppear(_ animated: Bool) { |
... | ... | @@ -32,22 +34,15 @@ final class TabsViewController: UIViewController { |
32 | 34 | } |
33 | 35 | |
34 | 36 | override func viewIsAppearing(_ animated: Bool) { |
37 | + navigationController?.isNavigationBarHidden = true | |
38 | + | |
35 | 39 | refreshData() |
36 | 40 | setCountOfTabs() |
37 | - navigationController?.isNavigationBarHidden = true | |
38 | 41 | } |
39 | 42 | |
40 | 43 | override func loadView() { |
41 | 44 | view = mainView |
42 | 45 | } |
43 | - | |
44 | - init() { | |
45 | - super.init(nibName: nil, bundle: nil) | |
46 | - } | |
47 | - | |
48 | - required init?(coder: NSCoder) { | |
49 | - fatalError("init(coder:) has not been implemented") | |
50 | - } | |
51 | 46 | } |
52 | 47 | |
53 | 48 | |
... | ... | @@ -59,12 +54,13 @@ extension TabsViewController: UICollectionViewDataSource, UICollectionViewDelega |
59 | 54 | |
60 | 55 | func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { |
61 | 56 | let tab = tabsData[indexPath.row] |
62 | - guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "OpenedTabsCollectionViewCell", for: indexPath) as? OpenedTabsCollectionViewCell else { | |
63 | - return OpenedTabsCollectionViewCell() | |
57 | + guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: OpenedTabsCollectionViewCell.cellID, for: indexPath) as? OpenedTabsCollectionViewCell else { | |
58 | + return UICollectionViewCell() | |
64 | 59 | } |
65 | 60 | cell.model = tab |
66 | 61 | cell.delegate = self |
67 | 62 | cell.closeTabButton.addTarget(self, action: #selector(closeTab(_:)), for: .touchUpInside) |
63 | + | |
68 | 64 | return cell |
69 | 65 | } |
70 | 66 | |
... | ... | @@ -77,30 +73,30 @@ extension TabsViewController: UICollectionViewDataSource, UICollectionViewDelega |
77 | 73 | pushSelectedTab(indexPath) |
78 | 74 | } |
79 | 75 | |
80 | - private func setupCollectionView() { | |
81 | - mainView.openedTabsCollectionView.dataSource = self | |
82 | - mainView.openedTabsCollectionView.delegate = self | |
83 | - mainView.openedTabsCollectionView.register(OpenedTabsCollectionViewCell.self, forCellWithReuseIdentifier: "OpenedTabsCollectionViewCell") | |
84 | - } | |
85 | 76 | } |
86 | 77 | |
87 | 78 | |
88 | 79 | //MARK: - Action |
89 | 80 | extension TabsViewController { |
90 | - func didTabButtonTapped(type: HistoryToolbarElementType) { | |
81 | + private func didTabButtonTapped(type: HistoryToolbarElementType) { | |
91 | 82 | switch type { |
92 | 83 | case .add: |
93 | 84 | addNewDefaultTab() |
94 | 85 | refreshData() |
86 | + | |
95 | 87 | let lastIndex = tabsData.endIndex - 1 |
96 | 88 | let lastIndexPath = IndexPath(row: lastIndex, section: 0) |
89 | + | |
97 | 90 | cellIndexPathForTransition = lastIndexPath |
98 | 91 | pushSelectedTab(lastIndexPath) |
99 | 92 | break |
93 | + | |
100 | 94 | case .done: |
101 | 95 | refreshData() |
96 | + | |
102 | 97 | let lastIndex = tabsData.endIndex - 1 |
103 | 98 | let lastIndexPath = IndexPath(row: lastIndex, section: 0) |
99 | + | |
104 | 100 | cellIndexPathForTransition = lastIndexPath |
105 | 101 | pushSelectedTab(lastIndexPath) |
106 | 102 | break |
... | ... | @@ -117,6 +113,12 @@ extension TabsViewController { |
117 | 113 | |
118 | 114 | //MARK: - Helpers |
119 | 115 | extension TabsViewController { |
116 | + private func setupCollectionView() { | |
117 | + mainView.openedTabsCollectionView.dataSource = self | |
118 | + mainView.openedTabsCollectionView.delegate = self | |
119 | + mainView.openedTabsCollectionView.register(OpenedTabsCollectionViewCell.self, forCellWithReuseIdentifier: OpenedTabsCollectionViewCell.cellID) | |
120 | + } | |
121 | + | |
120 | 122 | private func addTargets() { |
121 | 123 | addToolbarTargets() |
122 | 124 | } |
... | ... | @@ -129,8 +131,9 @@ extension TabsViewController { |
129 | 131 | return cellIndexPathForTransition ?? IndexPath(row: tabsData.count - 1, section: 0) |
130 | 132 | } |
131 | 133 | |
132 | - func addNewDefaultTab() { | |
134 | + private func addNewDefaultTab() { | |
133 | 135 | let defaultImage = UIImage(named: "defaultImage") |
136 | + | |
134 | 137 | TabManager.shared.saveTabWithComplition(tabTitle: "Start Page", snapshotImage: defaultImage, tabUrl: "homeUrl") { [weak self] result in |
135 | 138 | switch result { |
136 | 139 | default: |
... | ... | @@ -139,19 +142,22 @@ extension TabsViewController { |
139 | 142 | } |
140 | 143 | } |
141 | 144 | |
142 | - func pushSelectedTab(_ indexPath: IndexPath) { | |
145 | + private func pushSelectedTab(_ indexPath: IndexPath) { | |
143 | 146 | let index = indexPath.row |
147 | + | |
144 | 148 | if tabsData[index].TabUrl != "homeUrl" { |
145 | 149 | let browserHomeViewController = BrowserHomeViewController(url: tabsData[index].TabUrl, currentTabId: index) |
146 | 150 | browserHomeViewController.urlManagment(tabsData[index].TabUrl) |
151 | + | |
147 | 152 | navigationController?.pushViewController(browserHomeViewController, animated: true) |
148 | 153 | } else { |
149 | 154 | let browserHomeViewController = BrowserHomeViewController(url: tabsData[index].TabUrl, currentTabId: index) |
155 | + | |
150 | 156 | navigationController?.pushViewController(browserHomeViewController, animated: true) |
151 | 157 | } |
152 | 158 | } |
153 | 159 | |
154 | - func refreshData() { | |
160 | + private func refreshData() { | |
155 | 161 | tabsData = TabManager.shared.getAllTabs() |
156 | 162 | mainView.openedTabsCollectionView.reloadData() |
157 | 163 | } |
... | ... | @@ -163,20 +169,24 @@ extension TabsViewController: OpenedTabsCellDelegate { |
163 | 169 | guard let indexPath = mainView.openedTabsCollectionView.indexPath(for: cell) else { |
164 | 170 | return |
165 | 171 | } |
172 | + | |
166 | 173 | tabsData.remove(at: indexPath.row) |
174 | + | |
167 | 175 | mainView.openedTabsCollectionView.performBatchUpdates({ |
168 | 176 | mainView.openedTabsCollectionView.deleteItems(at: [indexPath]) |
169 | 177 | }, completion: { _ in |
170 | 178 | if self.tabsData.isEmpty { |
171 | 179 | self.addNewDefaultTab() |
172 | 180 | let browserHomeViewController = BrowserHomeViewController(url: "homeUrl", currentTabId: self.tabsData.count - 1) |
181 | + | |
173 | 182 | self.navigationController?.pushViewController(browserHomeViewController, animated: true) |
183 | + | |
174 | 184 | self.cellIndexPathForTransition = IndexPath(row: self.tabsData.count - 1, section: 0) |
175 | 185 | } |
176 | 186 | self.setCountOfTabs() |
177 | 187 | }) |
178 | 188 | } |
179 | - func setCountOfTabs() { | |
180 | - mainView.tabsToolbarView.showTabToolbarButtonItem.title = "\(tabsData.count) Tabs" | |
189 | + private func setCountOfTabs() { | |
190 | + mainView.tabsToolbarView.showedCountOfTabs.title = "\(tabsData.count) Tabs" | |
181 | 191 | } |
182 | 192 | } | ... | ... |
1 | +// | |
2 | +// OpenedTabsCellDelegate.swift | |
3 | +// browser | |
4 | +// | |
5 | +// Created by Artem Talko on 28.09.2023. | |
6 | +// | |
7 | +//MARK: Checked | |
8 | + | |
1 | 9 | import UIKit |
2 | 10 | import SnapKit |
3 | 11 | |
... | ... | @@ -6,6 +14,8 @@ protocol OpenedTabsCellDelegate: AnyObject { |
6 | 14 | } |
7 | 15 | |
8 | 16 | final class OpenedTabsCollectionViewCell: UICollectionViewCell { |
17 | + static let cellID = String(describing: OpenedTabsCollectionViewCell.self) | |
18 | + | |
9 | 19 | var model: BrowserTabDataBase? { |
10 | 20 | didSet { |
11 | 21 | handleUI() |
... | ... | @@ -14,20 +24,20 @@ final class OpenedTabsCollectionViewCell: UICollectionViewCell { |
14 | 24 | |
15 | 25 | weak var delegate: OpenedTabsCellDelegate? |
16 | 26 | |
17 | - let siteNameLabel: UILabel = { | |
27 | + private let siteNameLabel: UILabel = { | |
18 | 28 | let obj = UILabel() |
19 | 29 | obj.font = FontConstants.regularFont_14 |
20 | 30 | return obj |
21 | 31 | }() |
22 | 32 | |
23 | - let sitePreviewImageContainer: UIView = { | |
33 | + private let sitePreviewImageContainer: UIView = { | |
24 | 34 | let obj = UIView() |
25 | 35 | obj.clipsToBounds = true |
26 | 36 | obj.layer.cornerRadius = 10 |
27 | 37 | return obj |
28 | 38 | }() |
29 | 39 | |
30 | - let sitePreviewImage: UIImageView = { | |
40 | + private let sitePreviewImage: UIImageView = { | |
31 | 41 | let obj = UIImageView() |
32 | 42 | obj.contentMode = .scaleAspectFill |
33 | 43 | return obj |
... | ... | @@ -41,10 +51,11 @@ final class OpenedTabsCollectionViewCell: UICollectionViewCell { |
41 | 51 | return obj |
42 | 52 | }() |
43 | 53 | |
44 | - var panGestureRecognizer: UIPanGestureRecognizer! | |
54 | + private var panGestureRecognizer: UIPanGestureRecognizer! | |
45 | 55 | |
46 | 56 | override init(frame: CGRect) { |
47 | 57 | super.init(frame: frame) |
58 | + | |
48 | 59 | setup() |
49 | 60 | } |
50 | 61 | |
... | ... | @@ -52,14 +63,16 @@ final class OpenedTabsCollectionViewCell: UICollectionViewCell { |
52 | 63 | fatalError("init(coder:) has not been implemented") |
53 | 64 | } |
54 | 65 | |
55 | - func setup() { | |
66 | + private func setup() { | |
56 | 67 | self.backgroundColor = .white |
57 | 68 | layer.cornerRadius = 10 |
58 | - shadowSetup() | |
59 | 69 | contentView.addSubview(siteNameLabel) |
60 | 70 | contentView.addSubview(closeTabButton) |
61 | 71 | contentView.addSubview(sitePreviewImageContainer) |
72 | + | |
62 | 73 | sitePreviewImageContainer.addSubview(sitePreviewImage) |
74 | + | |
75 | + shadowSetup() | |
63 | 76 | setupConstraints() |
64 | 77 | addingTargets() |
65 | 78 | setupPanGesture() |
... | ... | @@ -81,8 +94,8 @@ final class OpenedTabsCollectionViewCell: UICollectionViewCell { |
81 | 94 | |
82 | 95 | sitePreviewImageContainer.snp.makeConstraints { make in |
83 | 96 | make.top.equalTo(closeTabButton.snp.bottom).offset(8) |
84 | - make.bottom.equalToSuperview().offset(-8) | |
85 | 97 | make.leading.trailing.equalToSuperview().inset(8) |
98 | + make.bottom.equalToSuperview().offset(-8) | |
86 | 99 | } |
87 | 100 | |
88 | 101 | sitePreviewImage.snp.makeConstraints { make in |
... | ... | @@ -92,6 +105,7 @@ final class OpenedTabsCollectionViewCell: UICollectionViewCell { |
92 | 105 | |
93 | 106 | override func layoutSubviews() { |
94 | 107 | super.layoutSubviews() |
108 | + | |
95 | 109 | shadowSetup() |
96 | 110 | } |
97 | 111 | } |
... | ... | @@ -100,17 +114,11 @@ final class OpenedTabsCollectionViewCell: UICollectionViewCell { |
100 | 114 | |
101 | 115 | //MARK: Helpers |
102 | 116 | extension OpenedTabsCollectionViewCell { |
103 | - func setupPanGesture() { | |
117 | + private func setupPanGesture() { | |
104 | 118 | panGestureRecognizer = UIPanGestureRecognizer(target: self, action: #selector(handlePan(_:))) |
105 | 119 | addGestureRecognizer(panGestureRecognizer) |
106 | 120 | } |
107 | 121 | |
108 | - func gestureRecognizer() { | |
109 | - let swipeRightGestureRecognizer = UISwipeGestureRecognizer(target: self, action: #selector(handleSwipe)) | |
110 | - swipeRightGestureRecognizer.direction = .right | |
111 | - addGestureRecognizer(swipeRightGestureRecognizer) | |
112 | - } | |
113 | - | |
114 | 122 | private func shadowSetup() { |
115 | 123 | layer.shadowColor = UIColor.black.withAlphaComponent(0.1).cgColor |
116 | 124 | layer.shadowOpacity = 1 |
... | ... | @@ -118,10 +126,9 @@ extension OpenedTabsCollectionViewCell { |
118 | 126 | layer.shadowOffset = CGSize(width: 0, height: 0) |
119 | 127 | } |
120 | 128 | |
121 | - func addingTargets() { | |
129 | + private func addingTargets() { | |
122 | 130 | closeTabButton.addTarget(self, action: #selector(deleteTab), for: .touchUpInside) |
123 | 131 | } |
124 | - | |
125 | 132 | } |
126 | 133 | |
127 | 134 | |
... | ... | @@ -139,17 +146,13 @@ extension OpenedTabsCollectionViewCell { |
139 | 146 | @objc |
140 | 147 | private func deleteTab() { |
141 | 148 | delegate?.deleteTabDelegateFunc(cell: self) |
149 | + | |
142 | 150 | if let tabId = model?.tabId { |
143 | 151 | TabManager.shared.deleteTab(tabId: tabId) |
144 | 152 | } |
145 | 153 | } |
146 | 154 | |
147 | 155 | @objc |
148 | - private func handleSwipe() { | |
149 | - deleteTab() | |
150 | - } | |
151 | - | |
152 | - @objc | |
153 | 156 | private func handlePan(_ gesture: UIPanGestureRecognizer) { |
154 | 157 | let translation = gesture.translation(in: self) |
155 | 158 | let width = self.frame.width | ... | ... |
... | ... | @@ -4,6 +4,7 @@ |
4 | 4 | // |
5 | 5 | // Created by Artem Talko on 28.09.2023. |
6 | 6 | // |
7 | +//MARK: Checked | |
7 | 8 | |
8 | 9 | import UIKit |
9 | 10 | |
... | ... | @@ -16,34 +17,39 @@ enum HistoryToolbarElementType { |
16 | 17 | final class TabsToolbarView: UIView { |
17 | 18 | var action: ((HistoryToolbarElementType) -> Void)? |
18 | 19 | |
19 | - let toolbar: UIToolbar = { | |
20 | + private let toolbar: UIToolbar = { | |
20 | 21 | let obj = UIToolbar() |
21 | 22 | obj.barTintColor = .white |
23 | + | |
22 | 24 | return obj |
23 | 25 | }() |
24 | 26 | |
25 | - let newTabToolbarButtonItem: UIBarButtonItem = { | |
27 | + private let newTabToolbarButtonItem: UIBarButtonItem = { | |
26 | 28 | let obj = UIBarButtonItem() |
27 | 29 | obj.image = UIImage(systemName: "plus") |
28 | 30 | obj.tintColor = .gray |
31 | + | |
29 | 32 | return obj |
30 | 33 | }() |
31 | 34 | |
32 | - | |
33 | - let showTabToolbarButtonItem: UIBarButtonItem = { | |
35 | + | |
36 | + let showedCountOfTabs: UIBarButtonItem = { | |
34 | 37 | let obj = UIBarButtonItem() |
35 | 38 | obj.tintColor = .gray |
39 | + | |
36 | 40 | return obj |
37 | 41 | }() |
38 | 42 | |
39 | - let doneTabToolbarButtonItem: UIBarButtonItem = { | |
43 | + private let doneTabToolbarButtonItem: UIBarButtonItem = { | |
40 | 44 | let obj = UIBarButtonItem() |
41 | 45 | obj.title = "Done" |
46 | + | |
42 | 47 | return obj |
43 | 48 | }() |
44 | 49 | |
45 | 50 | override init(frame: CGRect) { |
46 | 51 | super.init(frame: frame) |
52 | + | |
47 | 53 | setup() |
48 | 54 | } |
49 | 55 | |
... | ... | @@ -53,12 +59,8 @@ final class TabsToolbarView: UIView { |
53 | 59 | |
54 | 60 | private func setup() { |
55 | 61 | addSubview(toolbar) |
56 | - let flexibleSpace = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil) | |
57 | - toolbar.items = [ newTabToolbarButtonItem, | |
58 | - flexibleSpace, showTabToolbarButtonItem, | |
59 | - flexibleSpace, doneTabToolbarButtonItem ] | |
60 | 62 | |
61 | - toolbar.backgroundColor = .white | |
63 | + setupToolbar() | |
62 | 64 | initActions() |
63 | 65 | setupConstraints() |
64 | 66 | } |
... | ... | @@ -78,11 +80,21 @@ extension TabsToolbarView { |
78 | 80 | private func initActions() { |
79 | 81 | newTabToolbarButtonItem.target = self |
80 | 82 | newTabToolbarButtonItem.action = #selector(didItemTapped(_:)) |
81 | - showTabToolbarButtonItem.target = self | |
82 | - showTabToolbarButtonItem.action = #selector(didItemTapped(_:)) | |
83 | + | |
84 | + showedCountOfTabs.target = self | |
85 | + showedCountOfTabs.action = #selector(didItemTapped(_:)) | |
86 | + | |
83 | 87 | doneTabToolbarButtonItem.target = self |
84 | 88 | doneTabToolbarButtonItem.action = #selector(didItemTapped(_:)) |
85 | 89 | } |
90 | + | |
91 | + private func setupToolbar() { | |
92 | + let flexibleSpace = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil) | |
93 | + toolbar.items = [ newTabToolbarButtonItem, | |
94 | + flexibleSpace, showedCountOfTabs, | |
95 | + flexibleSpace, doneTabToolbarButtonItem ] | |
96 | + toolbar.backgroundColor = .white | |
97 | + } | |
86 | 98 | } |
87 | 99 | |
88 | 100 | // MARK: - Actions |
... | ... | @@ -93,14 +105,14 @@ extension TabsToolbarView { |
93 | 105 | return |
94 | 106 | } |
95 | 107 | switch sender { |
96 | - case newTabToolbarButtonItem: | |
97 | - action(.add) | |
98 | - case showTabToolbarButtonItem: | |
99 | - action(.tabs) | |
100 | - case doneTabToolbarButtonItem: | |
101 | - action(.done) | |
102 | - default: | |
103 | - break | |
108 | + case newTabToolbarButtonItem: | |
109 | + action(.add) | |
110 | + case showedCountOfTabs: | |
111 | + action(.tabs) | |
112 | + case doneTabToolbarButtonItem: | |
113 | + action(.done) | |
114 | + default: | |
115 | + break | |
104 | 116 | } |
105 | 117 | } |
106 | 118 | } | ... | ... |
... | ... | @@ -4,6 +4,7 @@ |
4 | 4 | // |
5 | 5 | // Created by Artem Talko on 28.09.2023. |
6 | 6 | // |
7 | +//MARK: Checked | |
7 | 8 | |
8 | 9 | import UIKit |
9 | 10 | import SnapKit |
... | ... | @@ -13,31 +14,35 @@ final class TabsView: UIView { |
13 | 14 | let obj = UICollectionViewFlowLayout() |
14 | 15 | obj.minimumInteritemSpacing = 4.sizeW |
15 | 16 | obj.sectionInset = UIEdgeInsets(top: 16.sizeH, left: 16.sizeW, bottom: 16.sizeH, right: 16.sizeW) |
17 | + | |
16 | 18 | let collectionView = UICollectionView(frame: .zero, collectionViewLayout: obj) |
17 | 19 | collectionView.showsVerticalScrollIndicator = false |
18 | 20 | collectionView.backgroundColor = .clear |
21 | + | |
19 | 22 | return collectionView |
20 | 23 | }() |
21 | 24 | |
22 | - let tabsToolbarView: TabsToolbarView = { | |
25 | + let tabsToolbarView: TabsToolbarView = { | |
23 | 26 | let obj = TabsToolbarView() |
24 | 27 | obj.backgroundColor = ColorConstants.lightGray |
28 | + | |
25 | 29 | return obj |
26 | 30 | }() |
27 | 31 | |
28 | 32 | override init(frame: CGRect) { |
29 | 33 | super.init(frame: frame) |
30 | - setup() | |
31 | - setupConstraints() | |
34 | + setupUI() | |
32 | 35 | } |
33 | 36 | |
34 | 37 | required init?(coder: NSCoder) { |
35 | 38 | fatalError("init(coder:) has not been implemented") |
36 | 39 | } |
37 | 40 | |
38 | - private func setup() { | |
41 | + private func setupUI() { | |
39 | 42 | addSubview(openedTabsCollectionView) |
40 | 43 | addSubview(tabsToolbarView) |
44 | + | |
45 | + setupConstraints() | |
41 | 46 | } |
42 | 47 | |
43 | 48 | private func setupConstraints() { |
... | ... | @@ -48,8 +53,8 @@ final class TabsView: UIView { |
48 | 53 | } |
49 | 54 | tabsToolbarView.snp.makeConstraints { make in |
50 | 55 | make.leading.equalToSuperview() |
51 | - make.trailing.equalToSuperview() | |
52 | 56 | make.bottom.equalTo(safeAreaLayoutGuide.snp.bottom) |
57 | + make.trailing.equalToSuperview() | |
53 | 58 | } |
54 | 59 | } |
55 | 60 | } | ... | ... |
... | ... | @@ -8,7 +8,6 @@ |
8 | 8 | import Foundation |
9 | 9 | |
10 | 10 | struct StringConstants { |
11 | - //static let shared = StringConstants() | |
12 | 11 | |
13 | 12 | ///PayloadView |
14 | 13 | static let ourBrowser = "Our browser lets you quickly and safely access \nthe internet. You can use it to look at web \npages, find information, and chat with friends." | ... | ... |
... | ... | @@ -18,7 +18,7 @@ |
18 | 18 | <subviews> |
19 | 19 | <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" image="Gotoweb" translatesAutoresizingMaskIntoConstraints="NO" id="M9l-6x-NJv"> |
20 | 20 | <rect key="frame" x="128" y="395" width="136" height="62"/> |
21 | - <autoresizingMask key="autoresizingMask"/> | |
21 | + <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> | |
22 | 22 | <edgeInsets key="layoutMargins" top="8" left="8" bottom="8" right="8"/> |
23 | 23 | </imageView> |
24 | 24 | </subviews> | ... | ... |
... | ... | @@ -12,6 +12,8 @@ final class SnapshotService { |
12 | 12 | static let shared = SnapshotService() |
13 | 13 | let snapshotConfiguration = WKSnapshotConfiguration() |
14 | 14 | |
15 | + private init() {} | |
16 | + | |
15 | 17 | func makeSnapshot(_ viewForSnap: UIView) -> UIImage { |
16 | 18 | let renderer = UIGraphicsImageRenderer(size: viewForSnap.bounds.size) |
17 | 19 | let siteSnapshotImage = renderer.image { (context) in | ... | ... |
Please
register
or
login
to post a comment