[ios] fix modal screen corner radius and shadows

Signed-off-by: Kiryl Kaveryn <kirylkaveryn@gmail.com>
This commit is contained in:
Kiryl Kaveryn 2025-03-14 18:25:13 +04:00
parent 692a92cb90
commit 1171c4f27d
Signed by: kirylkaveryn
SSH key fingerprint: SHA256:P3swI85Rc1ZoE8vyL28Oa6+FgRIaOwsjkKyqcVZ0NtY
7 changed files with 72 additions and 48 deletions

View file

@ -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 }

View file

@ -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
}
}
}
}

View file

@ -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
}

View file

@ -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

View file

@ -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) }

View file

@ -33,8 +33,7 @@ final class SearchOnMapHeaderView: UIView {
}
private func setupView() {
setStyle(.searchHeader)
layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner]
setStyle(.primaryBackground)
setupGrabberView()
setupSearchBar()

View file

@ -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