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