From c0af2c0c8ee76970871bf5458ef759b1d4ff2cf8 Mon Sep 17 00:00:00 2001 From: Alexander Boriskov Date: Tue, 7 Apr 2020 18:18:23 +0300 Subject: [PATCH] [iOS] Added swipe gesture to close PP on ipad https://jira.mail.ru/browse/MAPSME-13480 --- .../UIViewController+alternative.swift | 16 ++ .../Maps/Core/Theme/PlacePageStyleSheet.swift | 15 +- iphone/Maps/Maps.xcodeproj/project.pbxproj | 4 + .../PlacePageHeaderPresenter.swift | 8 +- .../PlacePageHeaderViewController.swift | 32 ++- iphone/Maps/UI/PlacePage/PlacePage.storyboard | 183 +++++++++++------- .../UI/PlacePage/PlacePagePresenter.swift | 6 +- .../PlacePage/PlacePageViewController.swift | 54 +++++- iphone/Maps/UI/Storyboard/Main.storyboard | 11 +- 9 files changed, 230 insertions(+), 99 deletions(-) create mode 100644 iphone/Maps/Categories/UIViewController+alternative.swift diff --git a/iphone/Maps/Categories/UIViewController+alternative.swift b/iphone/Maps/Categories/UIViewController+alternative.swift new file mode 100644 index 0000000000..6b2fdac9f3 --- /dev/null +++ b/iphone/Maps/Categories/UIViewController+alternative.swift @@ -0,0 +1,16 @@ +extension UIViewController { + func alternativeSizeClass(iPhone: @autoclosure () -> T, iPad: @autoclosure () -> T) -> T { + if traitCollection.verticalSizeClass == .regular && traitCollection.horizontalSizeClass == .regular { + return iPad() + } + return iPhone() + } + + func alternativeSizeClass(iPhone: () -> Void, iPad: () -> Void) { + if traitCollection.verticalSizeClass == .regular && traitCollection.horizontalSizeClass == .regular { + iPad() + } else { + iPhone() + } + } +} diff --git a/iphone/Maps/Core/Theme/PlacePageStyleSheet.swift b/iphone/Maps/Core/Theme/PlacePageStyleSheet.swift index da6be5c7ee..ad12606ecd 100644 --- a/iphone/Maps/Core/Theme/PlacePageStyleSheet.swift +++ b/iphone/Maps/Core/Theme/PlacePageStyleSheet.swift @@ -91,12 +91,12 @@ class PlacePageStyleSheet: IStyleSheet { s.clip = true } - theme.add(styleName: "PPNavigationBarView") { (s) -> (Void) in + theme.add(styleName: "PPNavigationShadowView") { (s) -> (Void) in s.backgroundColor = colors.white s.shadowColor = UIColor.black - s.shadowOffset = CGSize(width: 0, height: -1) - s.shadowOpacity = 1 - s.shadowOpacity = 0.6 + s.shadowOffset = CGSize(width: 0, height: 1) + s.shadowOpacity = 0.4 + s.shadowRadius = 1 s.clip = false } @@ -107,6 +107,13 @@ class PlacePageStyleSheet: IStyleSheet { s.shadowOffset = CGSize(width: 0, height: 1) s.shadowOpacity = 0.6 s.shadowRadius = 2 + s.clip = false + } + + theme.add(styleName: "PPView") { (s) -> (Void) in + s.backgroundColor = colors.clear + s.cornerRadius = 10 + s.clip = true } theme.add(styleName: "PPCloseButton") { (s) -> (Void) in diff --git a/iphone/Maps/Maps.xcodeproj/project.pbxproj b/iphone/Maps/Maps.xcodeproj/project.pbxproj index 2f4ba95895..d241300289 100644 --- a/iphone/Maps/Maps.xcodeproj/project.pbxproj +++ b/iphone/Maps/Maps.xcodeproj/project.pbxproj @@ -533,6 +533,7 @@ 67B78B551E42333C0018E590 /* AdSupport.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 67B78B541E42333C0018E590 /* AdSupport.framework */; }; 6B9978361C89A316003B8AA0 /* editor.config in Resources */ = {isa = PBXBuildFile; fileRef = 6B9978341C89A316003B8AA0 /* editor.config */; }; 7BD07E4A8D71CA41F082BEC7 /* Pods_MAPS_ME.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 58E5736C23FC4E77509C9946 /* Pods_MAPS_ME.framework */; }; + 99012847243F0D6900C72B10 /* UIViewController+alternative.swift in Sources */ = {isa = PBXBuildFile; fileRef = 99012846243F0D6900C72B10 /* UIViewController+alternative.swift */; }; 9917D17D2396793A00A7E06E /* PaidRoutesSubscriptionCampaign.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9917D17C2396793A00A7E06E /* PaidRoutesSubscriptionCampaign.swift */; }; 9917D17F2397B1D600A7E06E /* IPadModalPresentationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9917D17E2397B1D600A7E06E /* IPadModalPresentationController.swift */; }; 991CE2BF2371D349009EB02A /* PromoCampaignManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 991CE2BA2371D349009EB02A /* PromoCampaignManager.swift */; }; @@ -1598,6 +1599,7 @@ 8D1107310486CEB800E47090 /* MAPSME.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = MAPSME.plist; plistStructureDefinitionIdentifier = "com.apple.xcode.plist.structure-definition.iphone.info-plist"; sourceTree = ""; }; 978D4A30199A11E600D72CA7 /* faq.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; name = faq.html; path = ../../data/faq.html; sourceTree = ""; }; 97A5967E19B9CD47007A963F /* copyright.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; name = copyright.html; path = ../../data/copyright.html; sourceTree = ""; }; + 99012846243F0D6900C72B10 /* UIViewController+alternative.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIViewController+alternative.swift"; sourceTree = ""; }; 9917D17C2396793A00A7E06E /* PaidRoutesSubscriptionCampaign.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PaidRoutesSubscriptionCampaign.swift; sourceTree = ""; }; 9917D17E2397B1D600A7E06E /* IPadModalPresentationController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IPadModalPresentationController.swift; sourceTree = ""; }; 991CE2BA2371D349009EB02A /* PromoCampaignManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PromoCampaignManager.swift; sourceTree = ""; }; @@ -2775,6 +2777,7 @@ 34F7422F1E0834F400AC1FD6 /* UIViewController+Navigation.h */, 34F742301E0834F400AC1FD6 /* UIViewController+Navigation.m */, 33E905452180C40900868CAC /* UIViewController+Authorization.swift */, + 99012846243F0D6900C72B10 /* UIViewController+alternative.swift */, 347E03981FAC5F1D00426032 /* UIWindow+InputLanguage.swift */, 4767CDA320AAF66B00BD8166 /* NSAttributedString+HTML.swift */, 47699A0621F08E37009E6585 /* NSDate+TimeDistance.h */, @@ -5562,6 +5565,7 @@ 4716EABA21A325310029B886 /* IPaidRouteStatistics.swift in Sources */, 3490D2E11CE9DD2500D0B838 /* MWMSideButtonsView.mm in Sources */, 47F4F21523A6F06F0022FD56 /* AvailableMapsDataSource.swift in Sources */, + 99012847243F0D6900C72B10 /* UIViewController+alternative.swift in Sources */, 995739062355CAC40019AEE7 /* ImageViewCrossDisolve.swift in Sources */, 47B9065221C7FA400079C85E /* MWMWebImage.m in Sources */, F6E2FE7C1E097BA00083EBEC /* MWMPlacePageOpeningHoursCell.mm in Sources */, diff --git a/iphone/Maps/UI/PlacePage/Components/PlacePageHeader/PlacePageHeaderPresenter.swift b/iphone/Maps/UI/PlacePage/Components/PlacePageHeader/PlacePageHeaderPresenter.swift index 88c527a667..2084013f2e 100644 --- a/iphone/Maps/UI/PlacePage/Components/PlacePageHeader/PlacePageHeaderPresenter.swift +++ b/iphone/Maps/UI/PlacePage/Components/PlacePageHeader/PlacePageHeaderPresenter.swift @@ -36,11 +36,11 @@ extension PlacePageHeaderPresenter: PlacePageHeaderPresenterProtocol { view?.setTitle(placePagePreviewData.title ?? "") switch headerType { case .flexible: - view?.setViewStyle("PPHeaderView") - view?.setExpandViewEnabled(true) + view?.isExpandViewHidden = false + view?.isShadowViewHidden = true case .fixed: - view?.setViewStyle("PPNavigationBarView") - view?.setExpandViewEnabled(false) + view?.isExpandViewHidden = true + view?.isShadowViewHidden = false } } diff --git a/iphone/Maps/UI/PlacePage/Components/PlacePageHeader/PlacePageHeaderViewController.swift b/iphone/Maps/UI/PlacePage/Components/PlacePageHeader/PlacePageHeaderViewController.swift index ca99db0b14..7e6596e230 100644 --- a/iphone/Maps/UI/PlacePage/Components/PlacePageHeader/PlacePageHeaderViewController.swift +++ b/iphone/Maps/UI/PlacePage/Components/PlacePageHeader/PlacePageHeaderViewController.swift @@ -1,8 +1,9 @@ protocol PlacePageHeaderViewProtocol: class { var presenter: PlacePageHeaderPresenterProtocol? { get set } + var isExpandViewHidden: Bool { get set } + var isShadowViewHidden: Bool { get set } + func setTitle(_ title: String) - func setViewStyle(_ style: String) - func setExpandViewEnabled(_ val: Bool) } class PlacePageHeaderViewController: UIViewController { @@ -10,6 +11,7 @@ class PlacePageHeaderViewController: UIViewController { @IBOutlet private var titleLabel: UILabel! @IBOutlet private var expandView: UIView! + @IBOutlet private var shadowView: UIView! override func viewDidLoad() { super.viewDidLoad() @@ -28,15 +30,25 @@ class PlacePageHeaderViewController: UIViewController { } extension PlacePageHeaderViewController: PlacePageHeaderViewProtocol { + var isExpandViewHidden: Bool { + get { + expandView.isHidden + } + set { + expandView.isHidden = newValue + } + } + + var isShadowViewHidden: Bool { + get { + shadowView.isHidden + } + set { + shadowView.isHidden = newValue + } + } + func setTitle(_ title: String) { titleLabel.text = title } - - func setViewStyle(_ style: String) { - view.setStyleAndApply(style) - } - - func setExpandViewEnabled(_ val: Bool) { - expandView.isHidden = !val - } } diff --git a/iphone/Maps/UI/PlacePage/PlacePage.storyboard b/iphone/Maps/UI/PlacePage/PlacePage.storyboard index ddef76b472..153186a64a 100644 --- a/iphone/Maps/UI/PlacePage/PlacePage.storyboard +++ b/iphone/Maps/UI/PlacePage/PlacePage.storyboard @@ -18,12 +18,20 @@ + + + + + + + + @@ -36,6 +44,9 @@ + + + @@ -59,29 +70,44 @@ + + + + + + + + + + + + + + + @@ -3235,85 +3261,112 @@ - - - - - - - - - - - - - - - - - - - - - - + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - - - - - - - - - - - - - - - + + + + + + + + - - - - - + + + diff --git a/iphone/Maps/UI/PlacePage/PlacePagePresenter.swift b/iphone/Maps/UI/PlacePage/PlacePagePresenter.swift index 2002d06516..d988e5e88d 100644 --- a/iphone/Maps/UI/PlacePage/PlacePagePresenter.swift +++ b/iphone/Maps/UI/PlacePage/PlacePagePresenter.swift @@ -147,10 +147,6 @@ extension PlacePagePresenter: PlacePagePresenterProtocol { } func closeAnimated() { - view.scrollTo(CGPoint(x: 0, y: -self.view.scrollView.height + 1), - animated: true, - forced: true) { - self.view.scrollTo(CGPoint(x: 0, y: -self.view.scrollView.height), animated: false, forced: true) - } + view.closeAnimated() } } diff --git a/iphone/Maps/UI/PlacePage/PlacePageViewController.swift b/iphone/Maps/UI/PlacePage/PlacePageViewController.swift index 863ed34083..5c23c9c5f3 100644 --- a/iphone/Maps/UI/PlacePage/PlacePageViewController.swift +++ b/iphone/Maps/UI/PlacePage/PlacePageViewController.swift @@ -11,6 +11,7 @@ protocol PlacePageViewProtocol: class { func addNavigationBar(_ header: UIViewController) func scrollTo(_ point: CGPoint, animated: Bool, forced: Bool, completion: (()->())?) func layoutIfNeeded() + func closeAnimated() } extension PlacePageViewProtocol { @@ -30,6 +31,7 @@ final class PlacePageScrollView: UIScrollView { @IBOutlet var stackView: UIStackView! @IBOutlet var actionBarContainerView: UIView! @IBOutlet var actionBarHeightConstraint: NSLayoutConstraint! + @IBOutlet var panGesture: UIPanGestureRecognizer! var presenter: PlacePagePresenterProtocol! @@ -57,10 +59,11 @@ final class PlacePageScrollView: UIScrollView { override func viewDidLayoutSubviews() { super.viewDidLayoutSubviews() if previousTraitCollection == nil { - scrollView.contentInset = alternative(iPhone: UIEdgeInsets(top: scrollView.height, left: 0, bottom: 0, right: 0), - iPad: UIEdgeInsets.zero) + scrollView.contentInset = alternativeSizeClass(iPhone: UIEdgeInsets(top: scrollView.height, left: 0, bottom: 0, right: 0), + iPad: UIEdgeInsets.zero) presenter.updateSteps() } + panGesture.isEnabled = alternativeSizeClass(iPhone: false, iPad: true) self.previousTraitCollection = self.traitCollection } @@ -75,8 +78,29 @@ final class PlacePageScrollView: UIScrollView { DispatchQueue.main.async { self.presenter.updateSteps() self.presenter.showLastStop() - self.scrollView.contentInset = alternative(iPhone: UIEdgeInsets(top: self.scrollView.height, left: 0, bottom: 0, right: 0), - iPad: UIEdgeInsets.zero) + self.scrollView.contentInset = self.alternativeSizeClass(iPhone: UIEdgeInsets(top: self.scrollView.height, left: 0, bottom: 0, right: 0), + iPad: UIEdgeInsets.zero) + } + } + } + + @IBAction func onPan(gesture: UIPanGestureRecognizer){ + let xOffset = gesture.translation(in: view.superview).x + gesture.setTranslation(CGPoint.zero, in: view.superview) + view.minX += xOffset + view.minX = min(view.minX, 0) + let alpha = view.maxX / view.width + self.view.alpha = alpha + + let state = gesture.state + if state == .ended || state == .cancelled { + if alpha < 0.8 { + self.closeAnimated() + } else { + UIView.animate(withDuration: kDefaultAnimationDuration) { + self.view.minX = 0; + self.view.alpha = 1; + } } } } @@ -131,7 +155,7 @@ extension PlacePageViewController: PlacePageViewProtocol { } func scrollTo(_ point: CGPoint, animated: Bool, forced: Bool, completion: (()->())?) { - if alternative(iPhone: beginDragging, iPad: true) && !forced { + if alternativeSizeClass(iPhone: beginDragging, iPad: true) && !forced { return } if forced { @@ -141,6 +165,7 @@ extension PlacePageViewController: PlacePageViewProtocol { if animated { UIView.animate(withDuration: kDefaultAnimationDuration, animations: { [weak scrollView] in scrollView?.contentOffset = scrollPosition + self.layoutIfNeeded() }) { (complete) in if complete { completion?() @@ -155,6 +180,25 @@ extension PlacePageViewController: PlacePageViewProtocol { func layoutIfNeeded() { view.layoutIfNeeded() } + + func closeAnimated() { + alternativeSizeClass(iPhone: { + self.scrollTo(CGPoint(x: 0, y: -self.scrollView.height + 1), + animated: true, + forced: true) { + self.rootViewController.dismissPlacePage() + } + }, iPad: { + UIView.animate(withDuration: kDefaultAnimationDuration, + animations: { + let frame = self.view.frame + self.view.minX = frame.minX - frame.width + self.view.alpha = 0 + }) { (complete) in + self.rootViewController.dismissPlacePage() + } + }) + } } // MARK: - UIScrollViewDelegate diff --git a/iphone/Maps/UI/Storyboard/Main.storyboard b/iphone/Maps/UI/Storyboard/Main.storyboard index 02d662463e..b16a1e9e78 100644 --- a/iphone/Maps/UI/Storyboard/Main.storyboard +++ b/iphone/Maps/UI/Storyboard/Main.storyboard @@ -108,17 +108,12 @@ -