From d24b57406754ad4e953fa805145673cea2d62339 Mon Sep 17 00:00:00 2001 From: Alexandru Farcasanu Date: Tue, 14 Apr 2026 09:39:00 +0300 Subject: [PATCH] =?UTF-8?q?FXIOS-15074=20#32449=20=E2=81=83=20[Tracking=20?= =?UTF-8?q?Protection]=20Use=20native=20navigation=20bar?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Documentation.docc/ComponentLibrary.md | 1 - .../NavigationHeaderView.md | 21 --- .../Headers/NavigationHeaderView.swift | 155 ------------------ .../Headers/HeadersViewViewController.swift | 36 ++-- .../AccessibilityIdentifiers.swift | 6 - .../BlockedTrackersTableController.swift | 74 +++------ .../CertificatesViewController.swift | 82 +++------ ...ockedTrackersLearnMoreViewController.swift | 64 +++----- ...ckingProtectionDetailsViewController.swift | 72 +++----- .../TrackingProtectionViewController.swift | 2 + 10 files changed, 106 insertions(+), 407 deletions(-) delete mode 100644 BrowserKit/Sources/ComponentLibrary/Documentation.docc/General Components/NavigationHeaderView.md delete mode 100644 BrowserKit/Sources/ComponentLibrary/Headers/NavigationHeaderView.swift diff --git a/BrowserKit/Sources/ComponentLibrary/Documentation.docc/ComponentLibrary.md b/BrowserKit/Sources/ComponentLibrary/Documentation.docc/ComponentLibrary.md index 15c7c2a30eba2..4e9633ee9d7bb 100644 --- a/BrowserKit/Sources/ComponentLibrary/Documentation.docc/ComponentLibrary.md +++ b/BrowserKit/Sources/ComponentLibrary/Documentation.docc/ComponentLibrary.md @@ -36,7 +36,6 @@ Buildings blocks are classes uses by devs to enabled General or Feature componen - ``ContextualHintView`` - ``HeaderView`` - ``LinkButton`` -- ``NavigationHeaderView`` - ``PaddedSwitch`` - ``PrimaryRoundedButton`` - ``SecondaryRoundedButton`` diff --git a/BrowserKit/Sources/ComponentLibrary/Documentation.docc/General Components/NavigationHeaderView.md b/BrowserKit/Sources/ComponentLibrary/Documentation.docc/General Components/NavigationHeaderView.md deleted file mode 100644 index ae33f422b38f3..0000000000000 --- a/BrowserKit/Sources/ComponentLibrary/Documentation.docc/General Components/NavigationHeaderView.md +++ /dev/null @@ -1,21 +0,0 @@ -# ``ComponentLibrary/NavigationHeaderView`` - -The view which is used as a header for sheets, such as a bottom sheet, where some details are displayed, allowing navigation between screens. - -## Overview - -`NavigationHeaderView` is a subclass of `UIView`. It's a custom UIView that acts as a navigation header in an interface. It provides a title, a back button, and a close button, making it useful for navigation within menus or modal views. This view is ideal for use in navigation-driven applications where a header is needed to display a title and provide navigation controls for going back or closing a menu. - -## Illustration - -> This image is illustrative only. For precise examples of iOS implementation, please run the SampleApplication. - -@TabNavigator { - @Tab("Light") { - ![The NavigationHeaderView on iOS](NavigationHeaderView) - } - - @Tab("Dark") { - ![The NavigationHeaderView Dark on iOS](NavigationHeaderView-dark) - } -} diff --git a/BrowserKit/Sources/ComponentLibrary/Headers/NavigationHeaderView.swift b/BrowserKit/Sources/ComponentLibrary/Headers/NavigationHeaderView.swift deleted file mode 100644 index 1092dd14f34ef..0000000000000 --- a/BrowserKit/Sources/ComponentLibrary/Headers/NavigationHeaderView.swift +++ /dev/null @@ -1,155 +0,0 @@ -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/ - -import UIKit -import Common - -public final class NavigationHeaderView: UIView { - private struct UX { - static let closeButtonSize: CGFloat = 30 - static let imageMargins: CGFloat = 10 - static let baseDistance: CGFloat = 21 - static let horizontalMargin: CGFloat = 16 - static let separatorHeight: CGFloat = 1 - static let largeFaviconImageSize: CGFloat = 48 - } - - public var backToMainMenuCallback: (() -> Void)? - public var dismissMenuCallback: (() -> Void)? - - let titleLabel: UILabel = .build { label in - label.adjustsFontForContentSizeCategory = true - label.textAlignment = .center - label.font = FXFontStyles.Regular.headline.scaledFont() - label.numberOfLines = 2 - label.lineBreakMode = .byTruncatingTail - label.accessibilityTraits.insert(.header) - label.isAccessibilityElement = false - } - - private lazy var closeButton: CloseButton = .build { button in - button.addTarget(self, action: #selector(self.dismissMenuTapped), for: .touchUpInside) - } - - private lazy var backButton: UIButton = .build { button in - button.setImage(UIImage(imageLiteralResourceName: StandardImageIdentifiers.Large.chevronLeft) - .withRenderingMode(.alwaysTemplate), - for: .normal) - button.adjustsImageSizeForAccessibilityContentSizeCategory = true - button.imageView?.contentMode = .scaleAspectFit - button.titleLabel?.adjustsFontSizeToFitWidth = true - button.addTarget(self, action: #selector(self.backButtonTapped), for: .touchUpInside) - button.contentHorizontalAlignment = .leading - } - - private let horizontalLine: UIView = .build() - - private var backButtonText = "" - private var viewConstraints: [NSLayoutConstraint] = [] - - override init(frame: CGRect) { - super.init(frame: frame) - setupViews() - } - - required init?(coder: NSCoder) { - fatalError("init(coder:) has not been implemented") - } - - private func setupViews() { - addSubviews(titleLabel, backButton, closeButton, horizontalLine) - } - - // MARK: View Setup - private func updateLayout(isAccessibilityCategory: Bool) { - removeConstraints(constraints) - closeButton.removeConstraints(closeButton.constraints) - viewConstraints.removeAll() - viewConstraints.append(contentsOf: [ - backButton.leadingAnchor.constraint(equalTo: leadingAnchor, constant: UX.imageMargins), - backButton.centerYAnchor.constraint(equalTo: centerYAnchor), - - titleLabel.leadingAnchor.constraint(equalTo: backButton.trailingAnchor, - constant: UX.horizontalMargin), - titleLabel.trailingAnchor.constraint(lessThanOrEqualTo: closeButton.leadingAnchor, - constant: -UX.horizontalMargin), - titleLabel.centerXAnchor.constraint(equalTo: centerXAnchor), - titleLabel.topAnchor.constraint(equalTo: topAnchor, constant: UX.baseDistance), - titleLabel.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -UX.baseDistance), - - closeButton.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -UX.horizontalMargin), - closeButton.centerYAnchor.constraint(equalTo: centerYAnchor), - - horizontalLine.leadingAnchor.constraint(equalTo: leadingAnchor), - horizontalLine.trailingAnchor.constraint(equalTo: trailingAnchor), - horizontalLine.bottomAnchor.constraint(equalTo: bottomAnchor), - horizontalLine.heightAnchor.constraint(equalToConstant: UX.separatorHeight) - ]) - let closeButtonSizes = isAccessibilityCategory ? UX.largeFaviconImageSize : UX.closeButtonSize - viewConstraints.append(closeButton.heightAnchor.constraint(equalToConstant: closeButtonSizes)) - viewConstraints.append(closeButton.widthAnchor.constraint(equalToConstant: closeButtonSizes)) - closeButton.layer.cornerRadius = 0.5 * closeButtonSizes - NSLayoutConstraint.activate(viewConstraints) - } - - public func setupAccessibility(closeButtonA11yLabel: String, - closeButtonA11yId: String, - titleA11yId: String? = nil, - backButtonA11yLabel: String, - backButtonA11yId: String) { - let closeButtonViewModel = CloseButtonViewModel(a11yLabel: closeButtonA11yLabel, - a11yIdentifier: closeButtonA11yId) - closeButton.configure(viewModel: closeButtonViewModel) - if let titleA11yId { - titleLabel.isAccessibilityElement = true - titleLabel.accessibilityIdentifier = titleA11yId - } - backButton.accessibilityIdentifier = backButtonA11yId - backButton.accessibilityLabel = backButtonA11yLabel - } - - public func setViews(with title: String, and backButtonText: String) { - titleLabel.text = title - self.backButtonText = backButtonText - backButton.setTitle(backButtonText, for: .normal) - } - - public func adjustLayout() { - let isAccessibilityCategory = UIApplication.shared.preferredContentSizeCategory.isAccessibilityCategory - backButton.titleLabel?.font = FXFontStyles.Regular.body.scaledFont() - backButton.setTitle(isAccessibilityCategory ? "" : backButtonText, for: .normal) - updateLayout(isAccessibilityCategory: isAccessibilityCategory) - } - - public func updateHeaderLineView(isHidden: Bool) { - if (isHidden && !horizontalLine.isHidden) || (!isHidden && horizontalLine.isHidden) { - UIView.animate(withDuration: 0.3) { [weak self] in - self?.horizontalLine.isHidden = isHidden - } - } - } - - @objc - private func backButtonTapped() { - backToMainMenuCallback?() - } - - @objc - private func dismissMenuTapped() { - dismissMenuCallback?() - } - - // MARK: ThemeApplicable - public func applyTheme(theme: Theme) { - let buttonImage = UIImage(named: StandardImageIdentifiers.Medium.cross)? - .withTintColor(theme.colors.iconSecondary) - closeButton.setImage(buttonImage, for: .normal) - closeButton.backgroundColor = theme.colors.layer2 - backButton.tintColor = theme.colors.iconAccent - backButton.setTitleColor(theme.colors.textAccent, for: .normal) - horizontalLine.backgroundColor = theme.colors.borderPrimary - titleLabel.textColor = theme.colors.textPrimary - backgroundColor = theme.colors.layer3 - } -} diff --git a/SampleComponentLibraryApp/SampleComponentLibraryApp/Headers/HeadersViewViewController.swift b/SampleComponentLibraryApp/SampleComponentLibraryApp/Headers/HeadersViewViewController.swift index 8b19d44787afc..65c9e0c5d5f2f 100644 --- a/SampleComponentLibraryApp/SampleComponentLibraryApp/Headers/HeadersViewViewController.swift +++ b/SampleComponentLibraryApp/SampleComponentLibraryApp/Headers/HeadersViewViewController.swift @@ -8,7 +8,6 @@ import UIKit class HeadersViewViewController: UIViewController, Themeable { let headerTitle = "Website Title" - let backButtonTitle = "Back" let headerSubtitle = "Website Subtitle" let errorHeaderSubtitle = "Website Error" @@ -17,7 +16,6 @@ class HeadersViewViewController: UIViewController, Themeable { var themeObserver: NSObjectProtocol? var notificationCenter: NotificationProtocol = NotificationCenter.default - private lazy var navigationHeaderView: NavigationHeaderView = .build() private lazy var headerView: HeaderView = .build() private lazy var errorHeaderView: HeaderView = .build() @@ -37,13 +35,6 @@ class HeadersViewViewController: UIViewController, Themeable { listenForThemeChanges(withNotificationCenter: notificationCenter) applyTheme() - navigationHeaderView.setViews(with: headerTitle, and: backButtonTitle) - navigationHeaderView.adjustLayout() - navigationHeaderView.setupAccessibility(closeButtonA11yLabel: "CloseA11yLabel", - closeButtonA11yId: "CloseA11yId", - backButtonA11yLabel: "BackButtonA11yLabel", - backButtonA11yId: "BackButtonA11yId") - headerView.adjustLayout() errorHeaderView.adjustLayout() @@ -53,25 +44,31 @@ class HeadersViewViewController: UIViewController, Themeable { errorHeaderView.setupDetails(subtitle: errorHeaderSubtitle, title: headerTitle, icon: UIImage(named: StandardImageIdentifiers.Large.logoFirefox), - warningIcon: StandardImageIdentifiers.Large.criticalFill, + warningIcon: StandardImageIdentifiers.Large.warningFill, theme: themeManager.currentTheme) - headerView.setupAccessibility(closeButtonA11yLabel: "CloseA11yLabel", - closeButtonA11yId: "CloseA11yId") - errorHeaderView.setupAccessibility(closeButtonA11yLabel: "ErrorCloseA11yLabel", - closeButtonA11yId: "ErrorCloseA11yId") + headerView.setupAccessibility( + faviconA11yId: "FavIconA11yId", + titleLabelA11yId: "TitleA11yId", + subtitleLabelA11yId: "SubtitlesA11yId", + closeButtonA11yLabel: "CloseA11yLabel", + closeButtonA11yId: "CloseA11yId" + ) + errorHeaderView.setupAccessibility( + faviconA11yId: "ErrorFavIconA11yId", + titleLabelA11yId: "ErrorTitleA11yId", + subtitleLabelA11yId: "ErrorSubtitlesA11yId", + closeButtonA11yLabel: "ErrorCloseA11yLabel", + closeButtonA11yId: "ErrorCloseA11yId" + ) } private func setupView() { - view.addSubview(navigationHeaderView) view.addSubview(headerView) view.addSubview(errorHeaderView) NSLayoutConstraint.activate([ - navigationHeaderView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 20), - navigationHeaderView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 20), - navigationHeaderView.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -20), - headerView.topAnchor.constraint(equalTo: navigationHeaderView.bottomAnchor, constant: 40), + headerView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 20), headerView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 20), headerView.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -20), errorHeaderView.topAnchor.constraint(equalTo: headerView.bottomAnchor, constant: 40), @@ -87,7 +84,6 @@ class HeadersViewViewController: UIViewController, Themeable { // MARK: Themeable func applyTheme() { view.backgroundColor = themeManager.currentTheme.colors.layer1 - navigationHeaderView.applyTheme(theme: themeManager.currentTheme) headerView.applyTheme(theme: themeManager.currentTheme) errorHeaderView.applyTheme(theme: themeManager.currentTheme) } diff --git a/firefox-ios/Client/Application/AccessibilityIdentifiers.swift b/firefox-ios/Client/Application/AccessibilityIdentifiers.swift index 1b70cb0f54b61..05cafd81284e5 100644 --- a/firefox-ios/Client/Application/AccessibilityIdentifiers.swift +++ b/firefox-ios/Client/Application/AccessibilityIdentifiers.swift @@ -174,7 +174,6 @@ struct AccessibilityIdentifiers { struct DetailsScreen { static let scrollView = "TrackingProtectionDetails.ScrollView" - static let headerView = "TrackingProtectionDetails.HeaderView" static let mainView = "TrackingProtectionDetails.MainView" static let containerView = "TrackingProtectionDetails.BaseView" static let connectionView = "TrackingProtectionDetails.ConnectionView" @@ -218,16 +217,11 @@ struct AccessibilityIdentifiers { } struct BlockedTrackersLearnMore { - static let headerView = "BlockedTrackersLearnMore.HeaderView" static let containerView = "BlockedTrackersLearnMore.containerView" static let closeButton = "BlockedTrackersLearnMore.CloseButton" static let backButton = "BlockedTrackersLearnMore.BackButton" static let titleLabel = "BlockedTrackersLearnMore.TitleLabel" } - - struct CertificatesScreen { - static let headerView = "CertificatesViewController.HeaderView" - } } struct FirefoxHomepage { diff --git a/firefox-ios/Client/Frontend/TrackingProtection/BlockedTrackersTableController.swift b/firefox-ios/Client/Frontend/TrackingProtection/BlockedTrackersTableController.swift index cf40c54312d30..45f4e172cdbc2 100644 --- a/firefox-ios/Client/Frontend/TrackingProtection/BlockedTrackersTableController.swift +++ b/firefox-ios/Client/Frontend/TrackingProtection/BlockedTrackersTableController.swift @@ -34,12 +34,17 @@ class BlockedTrackersTableViewController: UIViewController, tableView.accessibilityIdentifier = A11y.trackersTable } - // MARK: Navigation View - private let navigationView: NavigationHeaderView = .build { header in - header.accessibilityIdentifier = AccessibilityIdentifiers.EnhancedTrackingProtection.BlockedTrackers.headerView + private lazy var closeButton: UIButton = .build { + $0.setImage( + UIImage(named: StandardImageIdentifiers.Large.cross)?.withRenderingMode(.alwaysTemplate), + for: .normal + ) + $0.addAction(UIAction(handler: { [weak self] _ in + self?.dismissVC() + }), for: .touchUpInside) + $0.showsLargeContentViewer = true } - private var constraints = [NSLayoutConstraint]() var model: BlockedTrackersTableModel var notificationCenter: NotificationProtocol var themeManager: ThemeManager @@ -82,47 +87,29 @@ class BlockedTrackersTableViewController: UIViewController, override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) + navigationController?.setNavigationBarHidden(false, animated: false) + updateViewDetails() applyTheme() } // MARK: View Setup private func setupView() { - constraints.removeAll() - setupNavigationView() + navigationItem.rightBarButtonItem = UIBarButtonItem(customView: closeButton) + setupTableView() setupAccessibilityIdentifiers() - setupHeaderViewActions() - NSLayoutConstraint.activate(constraints) - } - - // MARK: Header View Setup - private func setupNavigationView() { - view.addSubview(navigationView) - let navigationViewContraints = [ - navigationView.topAnchor.constraint( - equalTo: view.safeAreaLayoutGuide.topAnchor, - constant: TPMenuUX.UX.popoverTopDistance - ), - navigationView.trailingAnchor.constraint( - equalTo: view.trailingAnchor - ), - navigationView.leadingAnchor.constraint( - equalTo: view.leadingAnchor - ) - ] - constraints.append(contentsOf: navigationViewContraints) } // MARK: TableView Setup private func setupTableView() { view.addSubview(trackersTable) - let tableConstraints = [ + NSLayoutConstraint.activate([ trackersTable.leadingAnchor.constraint( equalTo: view.safeAreaLayoutGuide.leadingAnchor ), trackersTable.topAnchor.constraint( - equalTo: navigationView.bottomAnchor, + equalTo: view.topAnchor, constant: UX.headerDistance ), trackersTable.bottomAnchor.constraint( @@ -132,8 +119,7 @@ class BlockedTrackersTableViewController: UIViewController, trackersTable.trailingAnchor.constraint( equalTo: view.safeAreaLayoutGuide.trailingAnchor ) - ] - constraints.append(contentsOf: tableConstraints) + ]) } private func setupDataSource() { @@ -159,7 +145,7 @@ class BlockedTrackersTableViewController: UIViewController, } private func updateViewDetails() { - navigationView.setViews(with: model.topLevelDomain, and: .KeyboardShortcuts.Back) + self.title = model.topLevelDomain updateHeaderCount() } @@ -223,30 +209,15 @@ class BlockedTrackersTableViewController: UIViewController, return false } - @objc - func closeButtonTapped() { - self.dismiss(animated: true) - } - // MARK: Header Actions - private func setupHeaderViewActions() { - navigationView.backToMainMenuCallback = { [weak self] in - self?.navigationController?.popToRootViewController(animated: true) - } - navigationView.dismissMenuCallback = { [weak self] in - self?.navigationController?.dismissVC() - } + private func dismissVC() { + navigationController?.dismissVC() } // MARK: Accessibility private func setupAccessibilityIdentifiers() { - navigationView.setupAccessibility( - closeButtonA11yLabel: .Menu.EnhancedTrackingProtection.AccessibilityLabels.CloseButton, - closeButtonA11yId: AccessibilityIdentifiers.EnhancedTrackingProtection.DetailsScreen.closeButton, - titleA11yId: AccessibilityIdentifiers.EnhancedTrackingProtection.DetailsScreen.titleLabel, - backButtonA11yLabel: .Menu.EnhancedTrackingProtection.AccessibilityLabels.BackButton, - backButtonA11yId: AccessibilityIdentifiers.EnhancedTrackingProtection.DetailsScreen.backButton - ) + closeButton.accessibilityIdentifier = AccessibilityIdentifiers.EnhancedTrackingProtection.DetailsScreen.closeButton + closeButton.accessibilityLabel = .Menu.EnhancedTrackingProtection.AccessibilityLabels.CloseButton } // MARK: Notifications @@ -274,7 +245,6 @@ class BlockedTrackersTableViewController: UIViewController, } func adjustLayout() { - navigationView.adjustLayout() for cell in trackersTable.visibleCells { if let blockedTrackerCell = cell as? BlockedTrackerCell { blockedTrackerCell.invalidateIntrinsicContentSize() @@ -290,8 +260,8 @@ class BlockedTrackersTableViewController: UIViewController, func applyTheme() { let theme = currentTheme() - navigationView.applyTheme(theme: theme) trackersTable.applyTheme(theme: theme) + closeButton.tintColor = theme.colors.iconPrimary view.backgroundColor = theme.colors.layer3 } } diff --git a/firefox-ios/Client/Frontend/TrackingProtection/CertificatesViewController.swift b/firefox-ios/Client/Frontend/TrackingProtection/CertificatesViewController.swift index 97a7ea6afb60b..b18dbff30416c 100644 --- a/firefox-ios/Client/Frontend/TrackingProtection/CertificatesViewController.swift +++ b/firefox-ios/Client/Frontend/TrackingProtection/CertificatesViewController.swift @@ -47,10 +47,6 @@ class CertificatesViewController: UIViewController, label.adjustsFontSizeToFitWidth = true } - private let headerView: NavigationHeaderView = .build { header in - header.accessibilityIdentifier = AccessibilityIdentifiers.EnhancedTrackingProtection.CertificatesScreen.headerView - } - let certificatesTableView: UITableView = .build { tableView in tableView.allowsSelection = false tableView.register(CertificatesCell.self, forCellReuseIdentifier: CertificatesCell.cellIdentifier) @@ -60,6 +56,17 @@ class CertificatesViewController: UIViewController, tableView.separatorInset = .zero } + private lazy var closeButton: UIButton = .build { + $0.setImage( + UIImage(named: StandardImageIdentifiers.Large.cross)?.withRenderingMode(.alwaysTemplate), + for: .normal + ) + $0.addAction(UIAction(handler: { [weak self] _ in + self?.dismissVC() + }), for: .touchUpInside) + $0.showsLargeContentViewer = true + } + // MARK: - Variables private var constraints = [NSLayoutConstraint]() var model: CertificatesModel @@ -105,41 +112,16 @@ class CertificatesViewController: UIViewController, // MARK: View Setup private func setupView() { - setupHeaderView() + navigationItem.rightBarButtonItem = UIBarButtonItem(customView: closeButton) + setupTitleConstraints() setupCertificatesTableView() setupAccessibilityIdentifiers() } - // MARK: Header View Setup - private func setupHeaderView() { - view.addSubview(headerView) - NSLayoutConstraint.activate([ - headerView.leadingAnchor.constraint(equalTo: view.leadingAnchor), - headerView.trailingAnchor.constraint(equalTo: view.trailingAnchor), - headerView.topAnchor.constraint( - equalTo: view.safeAreaLayoutGuide.topAnchor, - constant: TPMenuUX.UX.popoverTopDistance - ) - ]) - setupHeaderViewActions() - } - // MARK: Header Actions - private func setupHeaderViewActions() { - headerView.backToMainMenuCallback = { [weak self] in - guard let self else { return } - let nav = self.navigationController - // When presented from error page we are the root of a modal nav stack; Back should dismiss. - if nav?.viewControllers.count == 1 { - nav?.dismissVC() - } else { - nav?.popViewController(animated: true) - } - } - headerView.dismissMenuCallback = { [weak self] in - self?.navigationController?.dismissVC() - } + private func dismissVC() { + navigationController?.dismissVC() } // MARK: Title Setup @@ -155,7 +137,7 @@ class CertificatesViewController: UIViewController, constant: -UX.titleLabelMargin ), titleLabel.topAnchor.constraint( - equalTo: headerView.bottomAnchor, + equalTo: view.safeAreaLayoutGuide.topAnchor, constant: UX.titleLabelTopMargin ) ]) @@ -272,39 +254,15 @@ class CertificatesViewController: UIViewController, // MARK: Accessibility private func setupAccessibilityIdentifiers() { typealias A11y = AccessibilityIdentifiers.EnhancedTrackingProtection.DetailsScreen - headerView.setupAccessibility( - closeButtonA11yLabel: .Menu.EnhancedTrackingProtection.AccessibilityLabels.CloseButton, - closeButtonA11yId: A11y.closeButton, - titleA11yId: A11y.titleLabel, - backButtonA11yLabel: .Menu.EnhancedTrackingProtection.AccessibilityLabels.BackButton, - backButtonA11yId: A11y.backButton - ) + closeButton.accessibilityIdentifier = A11y.closeButton + closeButton.accessibilityLabel = .Menu.EnhancedTrackingProtection.AccessibilityLabels.CloseButton titleLabel.accessibilityIdentifier = A11y.certificatesTitleLabel certificatesTableView.accessibilityIdentifier = A11y.tableView } - // MARK: View Transitions - override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) { - super.traitCollectionDidChange(previousTraitCollection) - adjustLayout() - } - - override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) { - super.viewWillTransition(to: size, with: coordinator) - coordinator.animate(alongsideTransition: { _ in - self.adjustLayout() - }, completion: nil) - } - - private func adjustLayout() { - headerView.adjustLayout() - view.setNeedsLayout() - view.layoutIfNeeded() - } - private func updateViewDetails() { certificatesTableView.reloadData() - headerView.setViews(with: model.topLevelDomain, and: .KeyboardShortcuts.Back) + self.title = model.topLevelDomain } // MARK: - Actions @@ -320,6 +278,6 @@ extension CertificatesViewController { view.backgroundColor = theme.colors.layer3 titleLabel.textColor = theme.colors.textPrimary titleLabel.backgroundColor = theme.colors.layer5 - headerView.applyTheme(theme: theme) + closeButton.tintColor = theme.colors.iconPrimary } } diff --git a/firefox-ios/Client/Frontend/TrackingProtection/TrackingDetailsHelpers/BlockedTrackersLearnMoreViewController.swift b/firefox-ios/Client/Frontend/TrackingProtection/TrackingDetailsHelpers/BlockedTrackersLearnMoreViewController.swift index 2083de7eb1e60..ac1524f834001 100644 --- a/firefox-ios/Client/Frontend/TrackingProtection/TrackingDetailsHelpers/BlockedTrackersLearnMoreViewController.swift +++ b/firefox-ios/Client/Frontend/TrackingProtection/TrackingDetailsHelpers/BlockedTrackersLearnMoreViewController.swift @@ -17,17 +17,22 @@ final class BlockedTrackersLearnMoreViewController: UIViewController, Themeable var currentWindowUUID: UUID? { return windowUUID } - // MARK: Navigation View - private let navigationView: NavigationHeaderView = .build { header in - typealias A11yIds = AccessibilityIdentifiers.EnhancedTrackingProtection.BlockedTrackersLearnMore - header.accessibilityIdentifier = A11yIds.headerView - } - private let containerView: UIView = .build { view in typealias A11yIds = AccessibilityIdentifiers.EnhancedTrackingProtection.BlockedTrackersLearnMore view.accessibilityIdentifier = A11yIds.containerView } + private lazy var closeButton: UIButton = .build { + $0.setImage( + UIImage(named: StandardImageIdentifiers.Large.cross)?.withRenderingMode(.alwaysTemplate), + for: .normal + ) + $0.addAction(UIAction(handler: { [weak self] _ in + self?.dismissVC() + }), for: .touchUpInside) + $0.showsLargeContentViewer = true + } + init(windowUUID: WindowUUID, notificationCenter: NotificationProtocol = NotificationCenter.default, themeManager: ThemeManager = AppContainer.shared.resolve(), @@ -54,41 +59,23 @@ final class BlockedTrackersLearnMoreViewController: UIViewController, Themeable } private func setupLayout() { - setupNavigationView() setupContainerView() embedChild() setupAccessibilityIdentifiers() - setupHeaderViewActions() - } - - // MARK: Header View Setup - private func setupNavigationView() { - view.addSubview(navigationView) - NSLayoutConstraint.activate([ - navigationView.topAnchor.constraint( - equalTo: view.safeAreaLayoutGuide.topAnchor, - constant: TPMenuUX.UX.popoverTopDistance - ), - navigationView.trailingAnchor.constraint( - equalTo: view.trailingAnchor - ), - navigationView.leadingAnchor.constraint( - equalTo: view.leadingAnchor - ) - ]) } private func setNavigationViewDetails() { - navigationView.setViews(with: url.baseDomain ?? "", and: .KeyboardShortcuts.Back) - navigationView.adjustLayout() + self.title = url.baseDomain ?? "" } // MARK: Container View Setup private func setupContainerView() { + navigationItem.rightBarButtonItem = UIBarButtonItem(customView: closeButton) + view.addSubview(containerView) NSLayoutConstraint.activate([ containerView.topAnchor.constraint( - equalTo: navigationView.bottomAnchor + equalTo: view.safeAreaLayoutGuide.topAnchor ), containerView.trailingAnchor.constraint( equalTo: view.trailingAnchor @@ -128,24 +115,15 @@ final class BlockedTrackersLearnMoreViewController: UIViewController, Themeable } // MARK: Header Actions - private func setupHeaderViewActions() { - navigationView.backToMainMenuCallback = { [weak self] in - self?.navigationController?.popViewController(animated: true) - } - navigationView.dismissMenuCallback = { [weak self] in - self?.navigationController?.dismissVC() - } + private func dismissVC() { + navigationController?.dismissVC() } // MARK: Accessibility private func setupAccessibilityIdentifiers() { - navigationView.setupAccessibility( - closeButtonA11yLabel: .Menu.EnhancedTrackingProtection.AccessibilityLabels.CloseButton, - closeButtonA11yId: AccessibilityIdentifiers.EnhancedTrackingProtection.BlockedTrackersLearnMore.closeButton, - titleA11yId: AccessibilityIdentifiers.EnhancedTrackingProtection.BlockedTrackersLearnMore.titleLabel, - backButtonA11yLabel: .Menu.EnhancedTrackingProtection.AccessibilityLabels.BackButton, - backButtonA11yId: AccessibilityIdentifiers.EnhancedTrackingProtection.BlockedTrackersLearnMore.backButton - ) + typealias A11y = AccessibilityIdentifiers.EnhancedTrackingProtection.BlockedTrackersLearnMore + closeButton.accessibilityIdentifier = A11y.closeButton + closeButton.accessibilityLabel = .Menu.EnhancedTrackingProtection.AccessibilityLabels.CloseButton } // MARK: - Themable @@ -155,7 +133,7 @@ final class BlockedTrackersLearnMoreViewController: UIViewController, Themeable func applyTheme() { let theme = currentTheme() - navigationView.applyTheme(theme: theme) + closeButton.tintColor = theme.colors.iconPrimary view.backgroundColor = theme.colors.layer3 } } diff --git a/firefox-ios/Client/Frontend/TrackingProtection/TrackingProtectionDetailsViewController.swift b/firefox-ios/Client/Frontend/TrackingProtection/TrackingProtectionDetailsViewController.swift index 007d1ffe7b269..d381003fbe9ce 100644 --- a/firefox-ios/Client/Frontend/TrackingProtection/TrackingProtectionDetailsViewController.swift +++ b/firefox-ios/Client/Frontend/TrackingProtection/TrackingProtectionDetailsViewController.swift @@ -48,9 +48,6 @@ class TrackingProtectionDetailsViewController: UIViewController, Themeable { stackView.distribution = .fill } - private let headerView: NavigationHeaderView = .build { header in - header.accessibilityIdentifier = AccessibilityIdentifiers.EnhancedTrackingProtection.DetailsScreen.headerView - } private let connectionView: TrackingProtectionStatusView = .build { view in view.accessibilityIdentifier = AccessibilityIdentifiers.EnhancedTrackingProtection.DetailsScreen.connectionView } @@ -58,6 +55,17 @@ class TrackingProtectionDetailsViewController: UIViewController, Themeable { view.accessibilityIdentifier = AccessibilityIdentifiers.EnhancedTrackingProtection.DetailsScreen.verifiedByView } + private lazy var closeButton: UIButton = .build { + $0.setImage( + UIImage(named: StandardImageIdentifiers.Large.cross)?.withRenderingMode(.alwaysTemplate), + for: .normal + ) + $0.addAction(UIAction(handler: { [weak self] _ in + self?.dismissVC() + }), for: .touchUpInside) + $0.showsLargeContentViewer = true + } + // MARK: See Certificates View private lazy var viewCertificatesButton: LinkButton = .build { button in button.titleLabel?.textAlignment = .left @@ -67,7 +75,6 @@ class TrackingProtectionDetailsViewController: UIViewController, Themeable { // MARK: - Variables - private var constraints = [NSLayoutConstraint]() var model: TrackingProtectionDetailsModel var notificationCenter: NotificationProtocol var themeManager: ThemeManager @@ -102,61 +109,43 @@ class TrackingProtectionDetailsViewController: UIViewController, Themeable { override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) + navigationController?.setNavigationBarHidden(false, animated: false) + updateViewDetails() } private func setupView() { - constraints.removeAll() - setupContentView() - setupHeaderView() setupConnectionStatusView() setupVerifiedByView() setupSeeCertificatesView() setupAccessibilityIdentifiers() - setupHeaderViewActions() - NSLayoutConstraint.activate(constraints) } // MARK: Content View Setup private func setupContentView() { + navigationItem.rightBarButtonItem = UIBarButtonItem(customView: closeButton) + view.addSubview(scrollView) scrollView.addSubview(baseView) - let contentViewContraints = [ - scrollView.topAnchor.constraint(equalTo: headerView.bottomAnchor), + NSLayoutConstraint.activate([ + scrollView.topAnchor.constraint(equalTo: view.topAnchor), scrollView.bottomAnchor.constraint( greaterThanOrEqualTo: view.bottomAnchor ), scrollView.leadingAnchor.constraint(equalTo: view.leadingAnchor), scrollView.trailingAnchor.constraint(equalTo: view.trailingAnchor), baseView.topAnchor.constraint( - equalTo: scrollView.topAnchor, - constant: UX.baseDistance + equalTo: scrollView.topAnchor ), baseView.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor), baseView.centerXAnchor.constraint(equalTo: scrollView.centerXAnchor), baseView.widthAnchor.constraint( equalTo: scrollView.widthAnchor, constant: -2 * TPMenuUX.UX.horizontalMargin - ), - ] - - constraints.append(contentsOf: contentViewContraints) - } - - // MARK: Header View Setup - private func setupHeaderView() { - view.addSubview(headerView) - let headerConstraints = [ - headerView.leadingAnchor.constraint(equalTo: view.leadingAnchor), - headerView.trailingAnchor.constraint(equalTo: view.trailingAnchor), - headerView.topAnchor.constraint( - equalTo: view.safeAreaLayoutGuide.topAnchor, - constant: TPMenuUX.UX.popoverTopDistance ) - ] - constraints.append(contentsOf: headerConstraints) + ]) } // MARK: Connection Status View Setup @@ -182,26 +171,16 @@ class TrackingProtectionDetailsViewController: UIViewController, Themeable { } // MARK: Header Actions - private func setupHeaderViewActions() { - headerView.backToMainMenuCallback = { [weak self] in - self?.navigationController?.popToRootViewController(animated: true) - } - headerView.dismissMenuCallback = { [weak self] in - self?.navigationController?.dismissVC() - } + private func dismissVC() { + navigationController?.dismissVC() } // MARK: Accessibility private func setupAccessibilityIdentifiers() { typealias A11y = AccessibilityIdentifiers.EnhancedTrackingProtection.DetailsScreen view.accessibilityIdentifier = AccessibilityIdentifiers.EnhancedTrackingProtection.DetailsScreen.mainView - headerView.setupAccessibility( - closeButtonA11yLabel: .Menu.EnhancedTrackingProtection.AccessibilityLabels.CloseButton, - closeButtonA11yId: A11y.closeButton, - titleA11yId: A11y.titleLabel, - backButtonA11yLabel: .Menu.EnhancedTrackingProtection.AccessibilityLabels.BackButton, - backButtonA11yId: A11y.backButton - ) + closeButton.accessibilityIdentifier = A11y.closeButton + closeButton.accessibilityLabel = .Menu.EnhancedTrackingProtection.AccessibilityLabels.CloseButton connectionView.setupAccessibilityIdentifiers( connectionImageA11yId: A11y.connectionImage, connectionStatusLabelA11yId: A11y.connectionStatusLabel, @@ -229,13 +208,12 @@ class TrackingProtectionDetailsViewController: UIViewController, Themeable { UIFontMetrics.default.scaledValue(for: iconSize), 2 * iconSize ) - headerView.adjustLayout() view.setNeedsLayout() view.layoutIfNeeded() } private func updateViewDetails() { - headerView.setViews(with: model.topLevelDomain, and: .KeyboardShortcuts.Back) + self.title = model.topLevelDomain connectionView.connectionStatusLabel.text = model.connectionStatusMessage if let certificate = model.certificates.first, let issuer = "\(certificate.issuer)".getDictionary()[CertificateKeys.commonName] { @@ -270,8 +248,8 @@ extension TrackingProtectionDetailsViewController { connectionView.connectionImage.image = model.getLockIcon(theme.type) verifiedByView.applyTheme(theme: theme) viewCertificatesButton.applyTheme(theme: theme) - headerView.applyTheme(theme: theme) connectionView.applyTheme(theme: theme) + closeButton.tintColor = theme.colors.iconPrimary setNeedsStatusBarAppearanceUpdate() } diff --git a/firefox-ios/Client/Frontend/TrackingProtection/TrackingProtectionViewController.swift b/firefox-ios/Client/Frontend/TrackingProtection/TrackingProtectionViewController.swift index 2182b2c928338..c61e654764ec7 100644 --- a/firefox-ios/Client/Frontend/TrackingProtection/TrackingProtectionViewController.swift +++ b/firefox-ios/Client/Frontend/TrackingProtection/TrackingProtectionViewController.swift @@ -216,6 +216,8 @@ class TrackingProtectionViewController: UIViewController, override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) + navigationController?.setNavigationBarHidden(true, animated: false) + updateBlockedTrackersCount() updateConnectionStatus() applyTheme()