From 1171c4f27d74daaa7cf2d0640854d9a18f4eb486 Mon Sep 17 00:00:00 2001 From: Kiryl Kaveryn Date: Fri, 14 Mar 2025 18:25:13 +0400 Subject: [PATCH] [ios] fix modal screen corner radius and shadows Signed-off-by: Kiryl Kaveryn --- iphone/Maps/Core/Theme/Core/Style.swift | 6 ++ iphone/Maps/Core/Theme/GlobalStyleSheet.swift | 18 +++++ .../Core/Theme/Renderers/UIViewRenderer.swift | 3 + iphone/Maps/Core/Theme/SearchStyleSheet.swift | 12 --- .../SearchOnMapPresentationController.swift | 1 + .../SearchOnMap/SearchOnMapHeaderView.swift | 3 +- .../SearchOnMapViewController.swift | 77 +++++++++++-------- 7 files changed, 72 insertions(+), 48 deletions(-) diff --git a/iphone/Maps/Core/Theme/Core/Style.swift b/iphone/Maps/Core/Theme/Core/Style.swift index 69c4b6bc9e..cef982070e 100644 --- a/iphone/Maps/Core/Theme/Core/Style.swift +++ b/iphone/Maps/Core/Theme/Core/Style.swift @@ -4,6 +4,7 @@ class Style: ExpressibleByDictionaryLiteral { case borderColor case borderWidth case cornerRadius + case maskedCorners case shadowColor case shadowOpacity case shadowOffset @@ -120,6 +121,11 @@ extension Style { set { params[.cornerRadius] = newValue } } + var maskedCorners: CACornerMask? { + get { return self[.maskedCorners] as? CACornerMask } + set { params[.maskedCorners] = newValue } + } + var shadowColor: UIColor? { get { return self[.shadowColor] as? UIColor } set { params[.shadowColor] = newValue } diff --git a/iphone/Maps/Core/Theme/GlobalStyleSheet.swift b/iphone/Maps/Core/Theme/GlobalStyleSheet.swift index 60590d985b..8de1a5fdcf 100644 --- a/iphone/Maps/Core/Theme/GlobalStyleSheet.swift +++ b/iphone/Maps/Core/Theme/GlobalStyleSheet.swift @@ -59,6 +59,8 @@ enum GlobalStyleSheet: String, CaseIterable { case white = "MWMWhite" case datePickerView = "DatePickerView" case valueStepperView = "ValueStepperView" + case modalSheetBackground + case modalSheetContent } extension GlobalStyleSheet: IStyleSheet { @@ -429,6 +431,22 @@ extension GlobalStyleSheet: IStyleSheet { s.fontColor = colors.blackPrimaryText s.coloring = MWMButtonColoring.blue } + case .modalSheetBackground: + return .add { s in + s.backgroundColor = colors.white + s.shadowColor = UIColor.black + s.shadowOffset = CGSize(width: 0, height: 1) + s.shadowOpacity = 0.4 + s.shadowRadius = 6 + s.cornerRadius = 12 + s.clip = false + s.maskedCorners = isIPad ? [] : [.layerMinXMinYCorner, .layerMaxXMinYCorner] + } + case .modalSheetContent: + return .addFrom(Self.modalSheetBackground) { s in + s.backgroundColor = colors.clear + s.clip = true + } } } } diff --git a/iphone/Maps/Core/Theme/Renderers/UIViewRenderer.swift b/iphone/Maps/Core/Theme/Renderers/UIViewRenderer.swift index 1369df1fe7..648c46f047 100644 --- a/iphone/Maps/Core/Theme/Renderers/UIViewRenderer.swift +++ b/iphone/Maps/Core/Theme/Renderers/UIViewRenderer.swift @@ -48,6 +48,9 @@ class UIViewRenderer { if let cornerRadius = style.cornerRadius { control.layer.cornerRadius = cornerRadius } + if let maskedCorners = style.maskedCorners { + control.layer.maskedCorners = maskedCorners + } if let clip = style.clip { control.clipsToBounds = clip } diff --git a/iphone/Maps/Core/Theme/SearchStyleSheet.swift b/iphone/Maps/Core/Theme/SearchStyleSheet.swift index a7fc9eb3f9..d9a9fbb40b 100644 --- a/iphone/Maps/Core/Theme/SearchStyleSheet.swift +++ b/iphone/Maps/Core/Theme/SearchStyleSheet.swift @@ -1,5 +1,4 @@ enum SearchStyleSheet: String, CaseIterable { - case searchHeader case searchCancelButton case searchInstallButton = "SearchInstallButton" case searchBanner = "SearchBanner" @@ -18,17 +17,6 @@ enum SearchStyleSheet: String, CaseIterable { extension SearchStyleSheet: IStyleSheet { func styleResolverFor(colors: IColors, fonts: IFonts) -> Theme.StyleResolver { switch self { - case .searchHeader: - return .add { s in - s.backgroundColor = colors.primary - iPhoneSpecific { - s.shadowColor = UIColor.black - s.shadowOffset = CGSize(width: 0, height: 1) - s.shadowOpacity = 0.5 - s.shadowRadius = 3 - s.cornerRadius = 10 - } - } case .searchInstallButton: return .add { s in s.cornerRadius = 10 diff --git a/iphone/Maps/UI/Search/SearchOnMap/Presentation/SearchOnMapPresentationController.swift b/iphone/Maps/UI/Search/SearchOnMap/Presentation/SearchOnMapPresentationController.swift index 2381216c57..f4ea79b98b 100644 --- a/iphone/Maps/UI/Search/SearchOnMap/Presentation/SearchOnMapPresentationController.swift +++ b/iphone/Maps/UI/Search/SearchOnMap/Presentation/SearchOnMapPresentationController.swift @@ -49,6 +49,7 @@ final class SearchOnMapPresentationController: NSObject { parentViewController.addChild(viewController) viewController.view.frame = frameOfPresentedViewInContainerView viewController.didMove(toParent: parentViewController) + viewController.view.setStyleAndApply(.modalSheetBackground) affectedAreas.forEach { $0.value?.addAffectingView(viewController.view) } diff --git a/iphone/Maps/UI/Search/SearchOnMap/SearchOnMapHeaderView.swift b/iphone/Maps/UI/Search/SearchOnMap/SearchOnMapHeaderView.swift index 361a6a27e1..560bf7a2e1 100644 --- a/iphone/Maps/UI/Search/SearchOnMap/SearchOnMapHeaderView.swift +++ b/iphone/Maps/UI/Search/SearchOnMap/SearchOnMapHeaderView.swift @@ -33,8 +33,7 @@ final class SearchOnMapHeaderView: UIView { } private func setupView() { - setStyle(.searchHeader) - layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner] + setStyle(.primaryBackground) setupGrabberView() setupSearchBar() diff --git a/iphone/Maps/UI/Search/SearchOnMap/SearchOnMapViewController.swift b/iphone/Maps/UI/Search/SearchOnMap/SearchOnMapViewController.swift index 95be2ece5a..31919ff9e6 100644 --- a/iphone/Maps/UI/Search/SearchOnMap/SearchOnMapViewController.swift +++ b/iphone/Maps/UI/Search/SearchOnMap/SearchOnMapViewController.swift @@ -26,8 +26,9 @@ final class SearchOnMapViewController: UIViewController { private var searchResults = SearchOnMap.SearchResults([]) // MARK: - UI Elements + let contentView = UIView() private let headerView = SearchOnMapHeaderView() - private let containerView = UIView() + private let searchResultsView = UIView() private let resultsTableView = UITableView() private let historyAndCategoryTabViewController = SearchTabViewController() private var searchingActivityView = PlaceholderView(hasActivityIndicator: true) @@ -71,7 +72,7 @@ final class SearchOnMapViewController: UIViewController { // MARK: - Private methods private func setupViews() { - view.setStyle(.clearBackground) + contentView.setStyle(.modalSheetContent) setupTapGestureRecognizer() setupHeaderView() setupContainerView() @@ -91,7 +92,7 @@ final class SearchOnMapViewController: UIViewController { } private func setupContainerView() { - containerView.setStyle(.background) + searchResultsView.setStyle(.background) } private func setupResultsTableView() { @@ -110,20 +111,28 @@ final class SearchOnMapViewController: UIViewController { } private func layoutViews() { - view.addSubview(headerView) - view.addSubview(containerView) + view.addSubview(contentView) + contentView.addSubview(headerView) + contentView.addSubview(searchResultsView) + + contentView.translatesAutoresizingMaskIntoConstraints = false headerView.translatesAutoresizingMaskIntoConstraints = false - containerView.translatesAutoresizingMaskIntoConstraints = false + searchResultsView.translatesAutoresizingMaskIntoConstraints = false NSLayoutConstraint.activate([ - headerView.topAnchor.constraint(equalTo: view.topAnchor), - headerView.leadingAnchor.constraint(equalTo: view.leadingAnchor), - headerView.trailingAnchor.constraint(equalTo: view.trailingAnchor), + contentView.topAnchor.constraint(equalTo: view.topAnchor), + contentView.leadingAnchor.constraint(equalTo: view.leadingAnchor), + contentView.trailingAnchor.constraint(equalTo: view.trailingAnchor), + contentView.bottomAnchor.constraint(equalTo: view.bottomAnchor), - containerView.topAnchor.constraint(equalTo: headerView.bottomAnchor), - containerView.leadingAnchor.constraint(equalTo: view.leadingAnchor), - containerView.trailingAnchor.constraint(equalTo: view.trailingAnchor), - containerView.bottomAnchor.constraint(equalTo: view.bottomAnchor), + headerView.topAnchor.constraint(equalTo: contentView.topAnchor), + headerView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor), + headerView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor), + + searchResultsView.topAnchor.constraint(equalTo: headerView.bottomAnchor), + searchResultsView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor), + searchResultsView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor), + searchResultsView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor), ]) layoutResultsView() @@ -133,48 +142,48 @@ final class SearchOnMapViewController: UIViewController { } private func layoutResultsView() { - containerView.addSubview(resultsTableView) + searchResultsView.addSubview(resultsTableView) resultsTableView.translatesAutoresizingMaskIntoConstraints = false NSLayoutConstraint.activate([ - resultsTableView.topAnchor.constraint(equalTo: containerView.topAnchor), - resultsTableView.leadingAnchor.constraint(equalTo: containerView.leadingAnchor), - resultsTableView.trailingAnchor.constraint(equalTo: containerView.trailingAnchor), - resultsTableView.bottomAnchor.constraint(equalTo: containerView.bottomAnchor) + resultsTableView.topAnchor.constraint(equalTo: searchResultsView.topAnchor), + resultsTableView.leadingAnchor.constraint(equalTo: searchResultsView.leadingAnchor), + resultsTableView.trailingAnchor.constraint(equalTo: searchResultsView.trailingAnchor), + resultsTableView.bottomAnchor.constraint(equalTo: searchResultsView.bottomAnchor) ]) } private func layoutHistoryAndCategoryTabView() { - containerView.addSubview(historyAndCategoryTabViewController.view) + searchResultsView.addSubview(historyAndCategoryTabViewController.view) historyAndCategoryTabViewController.view.translatesAutoresizingMaskIntoConstraints = false NSLayoutConstraint.activate([ - historyAndCategoryTabViewController.view.topAnchor.constraint(equalTo: containerView.topAnchor), - historyAndCategoryTabViewController.view.leadingAnchor.constraint(equalTo: containerView.leadingAnchor), - historyAndCategoryTabViewController.view.trailingAnchor.constraint(equalTo: containerView.trailingAnchor), - historyAndCategoryTabViewController.view.bottomAnchor.constraint(equalTo: containerView.bottomAnchor) + historyAndCategoryTabViewController.view.topAnchor.constraint(equalTo: searchResultsView.topAnchor), + historyAndCategoryTabViewController.view.leadingAnchor.constraint(equalTo: searchResultsView.leadingAnchor), + historyAndCategoryTabViewController.view.trailingAnchor.constraint(equalTo: searchResultsView.trailingAnchor), + historyAndCategoryTabViewController.view.bottomAnchor.constraint(equalTo: searchResultsView.bottomAnchor) ]) } private func layoutSearchNoResultsView() { searchNoResultsView.translatesAutoresizingMaskIntoConstraints = false - containerView.addSubview(searchNoResultsView) + searchResultsView.addSubview(searchNoResultsView) NSLayoutConstraint.activate([ - searchNoResultsView.topAnchor.constraint(equalTo: containerView.topAnchor), - searchNoResultsView.leadingAnchor.constraint(equalTo: containerView.leadingAnchor), - searchNoResultsView.trailingAnchor.constraint(equalTo: containerView.trailingAnchor), - searchNoResultsView.bottomAnchor.constraint(equalTo: containerView.bottomAnchor) + searchNoResultsView.topAnchor.constraint(equalTo: searchResultsView.topAnchor), + searchNoResultsView.leadingAnchor.constraint(equalTo: searchResultsView.leadingAnchor), + searchNoResultsView.trailingAnchor.constraint(equalTo: searchResultsView.trailingAnchor), + searchNoResultsView.bottomAnchor.constraint(equalTo: searchResultsView.bottomAnchor) ]) } private func layoutSearchingView() { - containerView.insertSubview(searchingActivityView, at: 0) + searchResultsView.insertSubview(searchingActivityView, at: 0) searchingActivityView.translatesAutoresizingMaskIntoConstraints = false NSLayoutConstraint.activate([ - searchingActivityView.leadingAnchor.constraint(equalTo: containerView.leadingAnchor), - searchingActivityView.trailingAnchor.constraint(equalTo: containerView.trailingAnchor), - searchingActivityView.topAnchor.constraint(equalTo: containerView.topAnchor), - searchingActivityView.bottomAnchor.constraint(equalTo: containerView.bottomAnchor) + searchingActivityView.leadingAnchor.constraint(equalTo: searchResultsView.leadingAnchor), + searchingActivityView.trailingAnchor.constraint(equalTo: searchResultsView.trailingAnchor), + searchingActivityView.topAnchor.constraint(equalTo: searchResultsView.topAnchor), + searchingActivityView.bottomAnchor.constraint(equalTo: searchResultsView.bottomAnchor) ]) } @@ -223,7 +232,7 @@ final class SearchOnMapViewController: UIViewController { historyAndCategoryTabViewController.view, searchNoResultsView, searchingActivityView].filter { $0 != view } - UIView.transition(with: containerView, + UIView.transition(with: searchResultsView, duration: kDefaultAnimationDuration / 2, options: [.transitionCrossDissolve, .curveEaseInOut], animations: { viewsToHide.forEach { viewToHide in