diff --git a/README.md b/README.md index 72b4dfa..306d4b1 100644 --- a/README.md +++ b/README.md @@ -50,8 +50,9 @@ Action item height ```swift - - standard - compact + - standard + - big ``` Spacer type diff --git a/Sources/UIFloatMenu.swift b/Sources/UIFloatMenu.swift index 5b63076..92bd0d6 100644 --- a/Sources/UIFloatMenu.swift +++ b/Sources/UIFloatMenu.swift @@ -15,25 +15,24 @@ class UIFloatMenu { return vc } - static private var initY = [CGFloat]() - static public var currentVC = UIViewController() + // Config static public var viewConfig = UIFloatMenuConfig() static public var headerConfig = UIFloatMenuHeaderConfig() + // Delegate + static public var delegate = Delegates() + + // KeyboardHelper static private var keyboardHelper: KeyboardHelper? - //MARK: - Config // Max view to show static private var maxView: Int = 3 // Animation duration static private var animationDuration: TimeInterval = 0.3 - // Delegate - static public var delegate = Delegates() - // Queue static private var queue = [UIFloatMenuQueue]() @@ -43,17 +42,11 @@ class UIFloatMenu { let correct = UIFloatMenuHelper.correctPosition(viewConfig.presentation) let id = UIFloatMenuID.genUUID(queue.count) - let menuView = UIFloatMenuView.init(items: actions, vc: currentVC, header: headerConfig, config: viewConfig, - delegate: delegate) + let menuView = UIFloatMenuView.init(items: actions, vc: currentVC, header: headerConfig, config: viewConfig, delegate: delegate) menuView.tag = id vc.view.addSubview(menuView) - let pan = UIPanGestureRecognizer(target: self, action: #selector(UIFloatMenuDrag(_:))) - pan.maximumNumberOfTouches = 1 - pan.cancelsTouchesInView = true - menuView.addGestureRecognizer(pan) - if case .default = correct { for gesture in menuView.gestureRecognizers! { gesture.isEnabled = true @@ -81,8 +74,6 @@ class UIFloatMenu { } showTo(menuView, positions: correct) - - initY.append(menuView.frame.origin.y) } else { print("Max view count") } @@ -103,61 +94,6 @@ class UIFloatMenu { } queue.removeAll() - initY.removeAll() - } - - //MARK: - UIFloatMenuDrag - @objc static private func UIFloatMenuDrag(_ sender: UIPanGestureRecognizer) { - let appRect = UIApplication.shared.windows[0].bounds - let topPadding = UIFloatMenuHelper.getPadding(.top) - let bottomPadding = UIFloatMenuHelper.getPadding(.bottom) - - let screen = topPadding + appRect.height + bottomPadding - - var dismissDragSize: CGFloat { - return bottomPadding.isZero ? screen - (topPadding*4.5) : screen - (bottomPadding*4) - } - - switch sender.state { - case .began: - break - case .changed: - panChanged(sender) - case .ended, .cancelled: - panEnded(sender, dismissDragSize: dismissDragSize) - case .failed, .possible: - break - @unknown default: - break - } - } - - // MARK: - panChanged() - static private func panChanged(_ gesture: UIPanGestureRecognizer) { - let view = gesture.view! - let translation = gesture.translation(in: gesture.view) - - var translationAmount = translation.y >= 0 ? translation.y : -pow(abs(translation.y), 0.5) - - let rubberBanding = true - - if !rubberBanding && translationAmount < 0 { translationAmount = 0 } - - view.transform = CGAffineTransform(translationX: 0, y: translationAmount) - } - - // MARK: - panEnded() - static private func panEnded(_ gesture: UIPanGestureRecognizer, dismissDragSize: CGFloat) { - let velocity = gesture.velocity(in: gesture.view).y - if ((gesture.view!.frame.origin.y+40) >= dismissDragSize) || (velocity > 180) { - NotificationCenter.default.post(name: NSNotification.Name("UIFloatMenuClose"), object: nil) - } else { - UIView.animate(withDuration: 0.2, animations: { - if let UIFloatMenu = currentVC.view.viewWithTag(queue.last!.uuid!) { - UIFloatMenu.transform = .identity - } - }) - } } // MARK: - closeMenu() @@ -229,7 +165,6 @@ class UIFloatMenu { } else { if animation { menuView.center = CGPoint(x: appRect.width/2, y: getPrepare) - let animator = UIViewPropertyAnimator(duration: animationDuration, dampingRatio: 1.0) { menuView.center.y = getShow } diff --git a/Sources/UIFloatMenuAction.swift b/Sources/UIFloatMenuAction.swift index f49f97e..1648c88 100644 --- a/Sources/UIFloatMenuAction.swift +++ b/Sources/UIFloatMenuAction.swift @@ -7,8 +7,9 @@ import UIKit //MARK: - heightStyle public enum heightStyle { - case standard case compact + case standard + case big } //MARK: - labelConfig diff --git a/Sources/UIFloatMenuConfig.swift b/Sources/UIFloatMenuConfig.swift index 1c02332..fc1065d 100644 --- a/Sources/UIFloatMenuConfig.swift +++ b/Sources/UIFloatMenuConfig.swift @@ -174,9 +174,6 @@ class UIFloatMenuID { let shared = UIFloatMenuID() static let backViewID = 100010001 - static let containerViewID = 200020002 - static let hideViewID = 300030003 - static let IDArray = [backViewID, containerViewID, hideViewID] static func genUUID(_ count: Int) -> Int { if count == 0 { diff --git a/Sources/UIFloatMenuController.swift b/Sources/UIFloatMenuController.swift index e755e66..5572a76 100644 --- a/Sources/UIFloatMenuController.swift +++ b/Sources/UIFloatMenuController.swift @@ -151,15 +151,15 @@ class UIFloatMenuController: UIViewController, UIGestureRecognizerDelegate { } else { let last = (queue.last?.config.presentation)! if case .rightDown(_) = last { - menu.showTo(menuView, positions: .default) + menu.showTo(menuView, positions: .default, animation: false) } else if case .rightUp(_) = last { - menu.showTo(menuView, positions: .default) + menu.showTo(menuView, positions: .default, animation: false) } else if case .leftUp(_) = last { - menu.showTo(menuView, positions: .default) + menu.showTo(menuView, positions: .default, animation: false) } else if case .leftDown(_) = last { - menu.showTo(menuView, positions: .default) + menu.showTo(menuView, positions: .default, animation: false) } else if case .default = last { - menu.showTo(menuView, positions: .default) + menu.showTo(menuView, positions: .default, animation: false) } else { menu.showTo(menuView, positions: last, iPad_window_width: 0) } @@ -202,12 +202,7 @@ class UIFloatMenuController: UIViewController, UIGestureRecognizerDelegate { for gesture in menuView.gestureRecognizers! { gesture.isEnabled = true } - } else if layout == .iPadHalfScreen{ - position = last - for gesture in menuView.gestureRecognizers! { - gesture.isEnabled = false - } - } else if layout == .iPadTwoThirdScreen { + } else if layout == .iPadHalfScreen || layout == .iPadTwoThirdScreen { position = last for gesture in menuView.gestureRecognizers! { gesture.isEnabled = false @@ -224,7 +219,7 @@ class UIFloatMenuController: UIViewController, UIGestureRecognizerDelegate { if Orientation.isLandscape { menuView.center = self.view.center } else { - menu.showTo(menuView, positions: UIFloatMenuHelper.correctPosition((self.queue.last?.config.presentation)!)) + menu.showTo(menuView, positions: UIFloatMenuHelper.correctPosition((self.queue.last?.config.presentation)!), animation: false) } } } diff --git a/Sources/UIFloatMenuView/Cell/UIFloatMenuActionCell.swift b/Sources/UIFloatMenuView/Cell/UIFloatMenuActionCell.swift index 0c3bb75..135f52a 100644 --- a/Sources/UIFloatMenuView/Cell/UIFloatMenuActionCell.swift +++ b/Sources/UIFloatMenuView/Cell/UIFloatMenuActionCell.swift @@ -120,7 +120,19 @@ class UIFloatMenuActionCell: UITableViewCell { contentStackView.translatesAutoresizingMaskIntoConstraints = false - let top_bottom: CGFloat = (itemHeight == .standard ? 10 : 7) + var top_bottom: CGFloat { + switch itemHeight { + case .standard: + return 10 + case .compact: + return 7 + case .big: + return 16 + case .none: + break + } + return 0 + } switch itemLayout { case .Icon_Title: diff --git a/Sources/UIFloatMenuView/UIFloatMenuView.swift b/Sources/UIFloatMenuView/UIFloatMenuView.swift index 4a71990..ad268e4 100644 --- a/Sources/UIFloatMenuView/UIFloatMenuView.swift +++ b/Sources/UIFloatMenuView/UIFloatMenuView.swift @@ -5,8 +5,8 @@ import UIKit -class UIFloatMenuView: UIView, UITableViewDelegate, UITableViewDataSource { - +class UIFloatMenuView: UIView, UITableViewDelegate, UITableViewDataSource, UIGestureRecognizerDelegate { + private var currentVC = UIViewController() private var config = UIFloatMenuConfig() @@ -24,7 +24,6 @@ class UIFloatMenuView: UIView, UITableViewDelegate, UITableViewDataSource { table.tag = UIFloatMenuID.backViewID table.translatesAutoresizingMaskIntoConstraints = false table.backgroundColor = .clear - table.isScrollEnabled = false table.clipsToBounds = true table.showsHorizontalScrollIndicator = false table.showsVerticalScrollIndicator = false @@ -92,6 +91,12 @@ class UIFloatMenuView: UIView, UITableViewDelegate, UITableViewDataSource { layer.masksToBounds = true layer.borderWidth = 0.5 layer.borderColor = UIColor.darkGray.withAlphaComponent(0.25).cgColor + + let pan = UIPanGestureRecognizer(target: self, action: #selector(UIFloatMenuDrag(_:))) + pan.maximumNumberOfTouches = 1 + pan.cancelsTouchesInView = true + pan.delegate = self + addGestureRecognizer(pan) } //MARK: - coder @@ -242,7 +247,14 @@ class UIFloatMenuView: UIView, UITableViewDelegate, UITableViewDataSource { let row = itemsData[indexPath.item] switch row.item { case .ActionCell(_, _, _, _, let heightStyle): - height = (heightStyle == .standard ? 57 : 47) + switch heightStyle { + case .standard: + height = 57 + case .compact: + height = 47 + case .big: + height = 67 + } case .Title(_): height = 30 case .Spacer(_): @@ -315,4 +327,70 @@ class UIFloatMenuView: UIView, UITableViewDelegate, UITableViewDataSource { return data } + //MARK: - UIFloatMenuDrag + @objc private func UIFloatMenuDrag(_ sender: UIPanGestureRecognizer) { + let appRect = UIApplication.shared.windows[0].bounds + let topPadding = UIFloatMenuHelper.getPadding(.top) + let bottomPadding = UIFloatMenuHelper.getPadding(.bottom) + + let screen = topPadding + appRect.height + bottomPadding + + var pointToDismiss: CGFloat { + return bottomPadding.isZero ? screen - (topPadding*4.5) : screen - (bottomPadding*4) + } + + switch sender.state { + case .began: + break + case .changed: + panChanged(sender) + case .ended, .cancelled: + panEnded(sender, point: pointToDismiss) + case .failed, .possible: + break + @unknown default: + break + } + } + + // MARK: - panChanged() + private func panChanged(_ gesture: UIPanGestureRecognizer) { + let view = gesture.view! + let translation = gesture.translation(in: gesture.view) + + var translationAmount = translation.y >= 0 ? translation.y : -pow(abs(translation.y), 0.55) + let rubberBanding = !tableView.isScrollEnabled + if !rubberBanding && translationAmount < 0 { translationAmount = 0 } + + view.transform = CGAffineTransform(translationX: 0, y: translationAmount) + } + + // MARK: - panEnded() + private func panEnded(_ gesture: UIPanGestureRecognizer, point: CGFloat) { + let velocity = gesture.velocity(in: gesture.view).y + let view = gesture.view! + if ((view.frame.origin.y+view.frame.height/1.6) >= point) || (velocity > 200) { + NotificationCenter.default.post(name: NSNotification.Name("UIFloatMenuClose"), object: nil) + } else { + UIView.animate(withDuration: 0.2, animations: { + self.transform = .identity + }) + } + } + + //MARK: - scrollViewDidScroll + func scrollViewDidScroll(_ scrollView: UIScrollView) { + if scrollView.contentOffset.y < 0 { + scrollView.contentOffset.y = 0 + } + } + + //MARK: - shouldRecognizeSimultaneouslyWith + func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool { + if tableView.contentOffset.y == 0 { + return true + } + return false + } + }