Files
OrderScheduling/Pods/DDUIGestureRecognizer/DDUIGestureRecognizer/Classes/DDUIPanGestureRecognizer/DDUIPanGestureRecognizer.swift
2023-12-28 17:23:28 +08:00

185 lines
6.7 KiB
Swift
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//
// DDUIPanGestureRecognizer.swift
// DDUIGestureRecognizer
// Created by DDIsFriend on 2023/12/19.
import Foundation
open class DDUIPanGestureRecognizer : UIPanGestureRecognizer {
public enum PanGestureFromType {
case bottom,top
}
public enum ExpandLevel {
case min,`default`,max
}
public struct PanGesValue {
///
public var from : PanGestureFromType = .bottom
///
public var minDisplayHeight : CGFloat = 0
///
public var defaultDisplayHeight : CGFloat = 0
///
public var maxDisplayHeight : CGFloat = 0
/// 0,1]
public var dragScale : CGFloat = 0.5
///
public var expandLevel : ExpandLevel = .min
internal var translationY : CGFloat = 0
internal var currentY : CGFloat = 0
}
public var panGesValue = PanGesValue.init()
public var expandLevelChangedHandler : ((_ oldExpandLevel: ExpandLevel, _ newExpandLevel: ExpandLevel) -> Void)?
///
/// - Parameter target: target
public init() {
super.init(target: nil, action: nil)
self.addTarget(self, action: #selector(panGesAction(ges: )))
}
/// targetaction
public override init(target: Any?, action: Selector?) {
super.init(target: target, action: action)
}
@objc fileprivate func panGesAction(ges: DDUIPanGestureRecognizer) {
baseAction(duration: 0.1) { viewFrame, minY, defaultY, maxY, currentY in
switch ges.state {
case .began:
currentY = viewFrame.origin.y
break
case .changed:
/// changedchangeddeltaY
let translationPoint = ges.translation(in: ges.view)
let deltaY = translationPoint.y - ges.panGesValue.translationY
ges.panGesValue.translationY = translationPoint.y
currentY = (viewFrame.origin.y) + deltaY
break
case .ended:
/// currentYmaxYdefaultY
let criticalYBetweenOfMaxYAndDefaultY = maxY - (maxY - defaultY) * ges.panGesValue.dragScale
if ges.panGesValue.currentY <= maxY && ges.panGesValue.currentY > criticalYBetweenOfMaxYAndDefaultY {
currentY = maxY
}else if ges.panGesValue.currentY > defaultY && ges.panGesValue.currentY <= criticalYBetweenOfMaxYAndDefaultY {
currentY = defaultY
}
/// currentYminYdefaultY
let criticalYBetweenOfMinYAndDefaultY = defaultY - (defaultY - minY) * ges.panGesValue.dragScale
if ges.panGesValue.currentY <= defaultY && ges.panGesValue.currentY > criticalYBetweenOfMinYAndDefaultY {
currentY = defaultY
}else if ges.panGesValue.currentY > minY && ges.panGesValue.currentY <= criticalYBetweenOfMinYAndDefaultY {
currentY = minY
}
ges.panGesValue.translationY = 0
break
default:
currentY = viewFrame.origin.y
break
}
}
}
func baseAction(duration: TimeInterval,baseActionHandler: (_ viewFrame: CGRect, _ minY: CGFloat, _ defaultY: CGFloat, _ maxY: CGFloat,_ currentY: inout CGFloat) -> Void) {
guard let superView = view?.superview else {
assert(false,"父类都没有,拖什么拖")
return
}
let superViewFrame = superView.frame
let viewFrame = view?.frame ?? .zero
let superViewH = superViewFrame.size.height
let viewH = viewFrame.size.height
switch panGesValue.from {
case .bottom:
/// viewyviewviewysuperViewyminYdeltaH
var minY = superViewH - panGesValue.maxDisplayHeight
let deltaH = superViewH - viewH
if deltaH > minY {
minY = deltaH
}
/// viewy
var maxY = superViewH - panGesValue.minDisplayHeight
if deltaH > maxY {
maxY = deltaH
}
/// y
var defaultY = superViewH - panGesValue.defaultDisplayHeight
if deltaH > defaultY {
defaultY = deltaH
}
var currentY : CGFloat = 0.0
///
baseActionHandler(viewFrame,minY,defaultY,maxY,&currentY)
/// y
if currentY < minY {
return
}
/// y
if currentY > maxY {
return
}
/// currentY
panGesValue.currentY = currentY
/// expandLevel
let oldExpandLevel = panGesValue.expandLevel
/// expandLevel
if panGesValue.currentY == minY {
panGesValue.expandLevel = .max
}else if panGesValue.currentY == maxY {
panGesValue.expandLevel = .min
}else if panGesValue.currentY == defaultY {
panGesValue.expandLevel = .default
}
/// expandLevel
let newExpandLevel = panGesValue.expandLevel
/// expandLevel
if oldExpandLevel != newExpandLevel {
if let expandLevelChangedHandler = expandLevelChangedHandler {
expandLevelChangedHandler(oldExpandLevel,newExpandLevel)
}
}
UIView.animate(withDuration: duration, animations: {[weak self] in
self?.view?.frame = CGRectMake(viewFrame.origin.x, currentY, viewFrame.size.width, viewFrame.size.height)
})
break
default:
break
}
}
public func expand(_ expand: ExpandLevel) {
baseAction(duration: 0.25) { viewFrame, minY, defaultY, maxY, currentY in
if expand == .max {
currentY = minY
}else if expand == .min {
currentY = maxY
}else if expand == .default {
currentY = defaultY
}
}
}
}