From 9ba955b8c6e4ec85b04b2afb0da337a4884238d6 Mon Sep 17 00:00:00 2001 From: iceboxi Date: Thu, 4 Jun 2020 12:15:40 +0800 Subject: [PATCH 1/3] make pop menu above source view --- PopMenu/Classes/PopMenuAppearance.swift | 3 +++ .../PopMenuViewController.swift | 17 +++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/PopMenu/Classes/PopMenuAppearance.swift b/PopMenu/Classes/PopMenuAppearance.swift index 9a4085d..2fa23ee 100644 --- a/PopMenu/Classes/PopMenuAppearance.swift +++ b/PopMenu/Classes/PopMenuAppearance.swift @@ -50,6 +50,9 @@ final public class PopMenuAppearance: NSObject { /// The presentation style public var popMenuPresentationStyle: PopMenuPresentationStyle = .cover() + + /// The menu will overlay on source view or not + public var popMenuAboveSourceView = false } diff --git a/PopMenu/View Controller & Views/PopMenuViewController.swift b/PopMenu/View Controller & Views/PopMenuViewController.swift index f2507f9..00e7b30 100644 --- a/PopMenu/View Controller & Views/PopMenuViewController.swift +++ b/PopMenu/View Controller & Views/PopMenuViewController.swift @@ -361,6 +361,23 @@ extension PopMenuViewController { desiredOrigin.x = minContentPos } + if appearance.popMenuAboveSourceView { + let minContentPos: CGFloat = UIScreen.main.bounds.size.height * 0.05 + let maxContentPos: CGFloat = UIScreen.main.bounds.size.height * 0.95 + + let offsetY = sourceFrame.size.height + desiredOrigin.y += offsetY + if (desiredOrigin.y + size.height) > maxContentPos { + desiredOrigin.y -= 2 * offsetY + } + if (desiredOrigin.y + size.height) > maxContentPos { + desiredOrigin.y = maxContentPos - size.height + } + if desiredOrigin.y < minContentPos { + desiredOrigin.y = minContentPos + } + } + // Move content in place translateOverflowX(desiredOrigin: &desiredOrigin, contentSize: size) translateOverflowY(desiredOrigin: &desiredOrigin, contentSize: size) From f6c04bbaa15f1f0c4163d78258d10188a63af84f Mon Sep 17 00:00:00 2001 From: iceboxi Date: Thu, 4 Jun 2020 16:10:31 +0800 Subject: [PATCH 2/3] User can custom pop menu shadow --- PopMenu/Classes/Helpers/UIView+Shadows.swift | 3 ++ PopMenu/Classes/PopMenuAppearance.swift | 28 +++++++++++++++++++ .../PopMenuViewController.swift | 2 +- 3 files changed, 32 insertions(+), 1 deletion(-) diff --git a/PopMenu/Classes/Helpers/UIView+Shadows.swift b/PopMenu/Classes/Helpers/UIView+Shadows.swift index c8ee08d..c2c200d 100644 --- a/PopMenu/Classes/Helpers/UIView+Shadows.swift +++ b/PopMenu/Classes/Helpers/UIView+Shadows.swift @@ -19,4 +19,7 @@ extension UIView { layer.masksToBounds = false } + public func addShadow(_ setting: PopMenuShadowColor) { + addShadow(offset: setting.offset, opacity: setting.opacity, radius: setting.radius, color: setting.color) + } } diff --git a/PopMenu/Classes/PopMenuAppearance.swift b/PopMenu/Classes/PopMenuAppearance.swift index 2fa23ee..04a5e56 100644 --- a/PopMenu/Classes/PopMenuAppearance.swift +++ b/PopMenu/Classes/PopMenuAppearance.swift @@ -54,6 +54,8 @@ final public class PopMenuAppearance: NSObject { /// The menu will overlay on source view or not public var popMenuAboveSourceView = false + /// The menu shadow setting + public var popMenuShadowColor: PopMenuShadowColor = .default() } /// Background styles for PopMenu. @@ -202,3 +204,29 @@ public enum PopMenuDirection { case bottom case none } + +/// Menu Shadow setting structure to control PopMenu shadow. +public struct PopMenuShadowColor { + + /// Shadow offset. + public let offset: CGSize + + /// Shadow opacity. + public let opacity: Float + + /// Shadow radius. + public let radius: CGFloat + + /// Shadow color. + public let color: Color + + /// Get shadow's color instance with default setting + public static func `default`() -> PopMenuShadowColor { + return PopMenuShadowColor(offset: .init(width: 0, height: 1), opacity: 0.5, radius: 20, color: .black) + } + + /// Get shadow's color instance with custom setting + public static func custom(offset: CGSize = .zero, opacity: Float = 0.65, radius: CGFloat = 20, color: Color = .black) -> PopMenuShadowColor { + return PopMenuShadowColor(offset: offset, opacity: opacity, radius: radius, color: color) + } +} diff --git a/PopMenu/View Controller & Views/PopMenuViewController.swift b/PopMenu/View Controller & Views/PopMenuViewController.swift index 00e7b30..8a4a9bf 100644 --- a/PopMenu/View Controller & Views/PopMenuViewController.swift +++ b/PopMenu/View Controller & Views/PopMenuViewController.swift @@ -260,7 +260,7 @@ extension PopMenuViewController { /// Setup the content view. fileprivate func configureContentView() { containerView.translatesAutoresizingMaskIntoConstraints = false - containerView.addShadow(offset: .init(width: 0, height: 1), opacity: 0.5, radius: 20) + containerView.addShadow(appearance.popMenuShadowColor) containerView.layer.cornerRadius = appearance.popMenuCornerRadius containerView.backgroundColor = .clear From d03c483b398f92e9366003b0dc68d5dd2bde9ab7 Mon Sep 17 00:00:00 2001 From: iceboxi Date: Thu, 4 Nov 2021 16:36:31 +0800 Subject: [PATCH 3/3] fix: swift update --- PopMenu/Classes/Helpers/Haptics.swift | 3 +-- PopMenu/View Controller & Views/PopMenuViewController.swift | 6 +++++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/PopMenu/Classes/Helpers/Haptics.swift b/PopMenu/Classes/Helpers/Haptics.swift index a0c46dc..4ca732d 100644 --- a/PopMenu/Classes/Helpers/Haptics.swift +++ b/PopMenu/Classes/Helpers/Haptics.swift @@ -9,14 +9,13 @@ import UIKit /// Haptic Generator Helper. +@available(iOS 10.0, *) public enum Haptic { /// Impact style. - @available(iOS 10.0, *) case impact(UIImpactFeedbackGenerator.FeedbackStyle) /// Notification style. - @available(iOS 10.0, *) case notification(UINotificationFeedbackGenerator.FeedbackType) /// Selection style. diff --git a/PopMenu/View Controller & Views/PopMenuViewController.swift b/PopMenu/View Controller & Views/PopMenuViewController.swift index 8a4a9bf..90ad36c 100644 --- a/PopMenu/View Controller & Views/PopMenuViewController.swift +++ b/PopMenu/View Controller & Views/PopMenuViewController.swift @@ -582,7 +582,11 @@ extension PopMenuViewController { guard !action.highlighted else { return } if shouldEnableHaptics { - Haptic.selection.generate() + if #available(iOS 10.0, *) { + Haptic.selection.generate() + } else { + // Fallback on earlier versions + } } // Highlight current action view.