@@ -25,6 +25,8 @@ public class UBottomSheetCoordinator {
2525 private var draggables : [ DraggableItem ] = [ ]
2626 ///Drop shadow view behind container.
2727 private var dropShadowView : PassThroughView ?
28+ /// accept difference equal if in tolerance
29+ private var tolerance : CGFloat = 0.0000001
2830
2931 public var availableHeight : CGFloat {
3032 return parent. view. frame. height
@@ -118,13 +120,12 @@ public class UBottomSheetCoordinator {
118120 let container = PassThroughView ( )
119121 self . container = container
120122 parent. view. addSubview ( container)
121- parent. ub_add ( item, in: container, topInset: dataSource. sheetPositions ( availableHeight) . min ( ) !)
123+ let position = dataSource. initialPosition ( availableHeight)
124+ parent. ub_add ( item, in: container, topInset: position) { [ weak self] in
125+ guard let sSelf = self else { return }
126+ sSelf. delegate? . bottomSheet ( container, didPresent: . finished( position, sSelf. calculatePercent ( at: position) ) )
127+ }
122128 didContainerCreate ? ( container)
123- container. translatesAutoresizingMaskIntoConstraints = true
124- let y = dataSource. sheetPositions ( availableHeight) [ 0 ]
125- container. frame = CGRect ( x: 0 , y: y, width: parent. view. frame. width, height: parent. view. frame. height - y)
126- // container.pinToEdges(to: parent.view)
127- // container.constraint(parent, for: .top)?.constant = dataSource.sheetPositions(availableHeight)[0]
128129 setPosition ( dataSource. initialPosition ( availableHeight) , animated: false )
129130 }
130131
@@ -138,10 +139,11 @@ public class UBottomSheetCoordinator {
138139 }
139140
140141 public func addDropShadowIfNotExist( _ config: ( ( UIView ) -> Void ) ? = nil ) {
141- guard self . dropShadowView == nil else { return }
142- self . dropShadowView = PassThroughView ( )
142+ guard dropShadowView == nil else { return }
143+ dropShadowView = PassThroughView ( )
143144 parent. view. insertSubview ( dropShadowView!, belowSubview: container!)
144- self . dropShadowView? . pinToEdges ( to: container!, insets: UIEdgeInsets ( top: - container!. frame. minY, left: 0 , bottom: 0 , right: 0 ) )
145+ dropShadowView? . pinToEdges ( to: container!, insets: UIEdgeInsets ( top: - getInitialFrame( ) . minY, left: 0 , bottom: 0 , right: 0 ) )
146+
145147 self . dropShadowView? . layer. masksToBounds = false
146148 if config == nil {
147149 applyDefaultShadowParams ( )
@@ -151,18 +153,33 @@ public class UBottomSheetCoordinator {
151153 }
152154 }
153155
156+ private func getInitialFrame( ) -> CGRect {
157+ let minY = parent. view. bounds. minY + dataSource. initialPosition ( availableHeight)
158+ return CGRect ( x: parent. view. bounds. minX,
159+ y: minY,
160+ width: parent. view. bounds. width,
161+ height: parent. view. bounds. maxY - minY)
162+ }
163+
154164 private func applyDefaultShadowParams( ) {
155- dropShadowView? . layer. shadowPath = UIBezierPath ( roundedRect: container! . frame , cornerRadius: cornerRadius) . cgPath
165+ dropShadowView? . layer. shadowPath = UIBezierPath ( roundedRect: getInitialFrame ( ) , cornerRadius: cornerRadius) . cgPath
156166 dropShadowView? . layer. shadowColor = UIColor . black. cgColor
157167 dropShadowView? . layer. shadowRadius = CGFloat . init ( 10 )
158- dropShadowView? . layer. shadowOpacity = Float . init ( 0.5 )
168+ // dropShadowView?.layer.shadowOpacity = Float.init(0.5)
159169 dropShadowView? . layer. shadowOffset = CGSize . init ( width: 0.0 , height: 4.0 )
170+ let animation = CABasicAnimation ( keyPath: " shadowOpacity " )
171+ animation. fromValue = 0.0
172+ animation. toValue = 0.5
173+ animation. isRemovedOnCompletion = false
174+ animation. fillMode = . forwards
175+ animation. duration = 0.3
176+ dropShadowView? . layer. add ( animation, forKey: " fadeout " )
160177 }
161178
162179 private func clearShadowBackground( ) {
163180 let p = CGMutablePath ( )
164- p. addRect ( parent. view. bounds)
165- p. addPath ( UIBezierPath ( roundedRect: container! . frame , cornerRadius: cornerRadius) . cgPath)
181+ p. addRect ( parent. view. bounds. insetBy ( dx : 0 , dy : - availableHeight ) )
182+ p. addPath ( UIBezierPath ( roundedRect: getInitialFrame ( ) , cornerRadius: cornerRadius) . cgPath)
166183 let mask = CAShapeLayer ( )
167184 mask. path = p
168185 mask. fillRule = . evenOdd
@@ -294,7 +311,7 @@ public class UBottomSheetCoordinator {
294311 case . changed:
295312 if let scroll = scrollView{
296313 switch dragDirection ( vel) {
297- case . up where ( container!. frame. minY - minSheetPosition! > 0.001 ) :
314+ case . up where ( container!. frame. minY - minSheetPosition! > tolerance ) :
298315 translate ( dy: dy - lastY)
299316 scroll. contentOffset. y = lastContentOffset. y
300317 case . down where scroll. contentOffset. y <= 0 && !scroll. isDecelerating:
@@ -303,30 +320,25 @@ public class UBottomSheetCoordinator {
303320 default :
304321 break
305322 }
306- // if vel.y < 0 /*dragging up*/ && (container!.frame.minY - minSheetPosition! > 0.001){
307- // translate(dy: dy - lastY)
308- // scroll.contentOffset.y = lastContentOffset.y
309- // }else if vel.y > 0 /*dragging down*/ && scroll.contentOffset.y <= 0 && !scroll.isDecelerating{
310- // translate(dy: dy - lastY)
311- // scroll.contentOffset.y = 0
312- // }
313323 } else {
314324 translate ( dy: dy)
315325 }
316- case . ended, . cancelled, . failed:
326+ case . ended,
327+ . cancelled,
328+ . failed:
317329 if let scroll = scrollView{
318330 let minY = container!. frame. minY
319331 switch dragDirection ( vel) {
320- case . up where minY - minSheetPosition! > 0.001 :
332+ case . up where minY - minSheetPosition! > tolerance :
321333 scroll. setContentOffset ( lastContentOffset, animated: false )
322- self . finishDragging ( with: vel)
334+ self . finishDragging ( with: vel, position : minY )
323335 default :
324336 if !isSheetPosition( minY) {
325- self . finishDragging ( with: vel)
337+ self . finishDragging ( with: vel, position : minY )
326338 }
327339 }
328340 } else {
329- self . finishDragging ( with: vel)
341+ self . finishDragging ( with: vel, position : container! . frame . minY + dy )
330342 }
331343 default : break
332344 }
@@ -346,7 +358,7 @@ public class UBottomSheetCoordinator {
346358 */
347359 private func isSheetPosition( _ point: CGFloat ) -> Bool {
348360 return dataSource. sheetPositions ( availableHeight) . first ( where: { ( p) -> Bool in
349- abs ( p - point) < 0.001
361+ abs ( p - point) < tolerance
350362 } ) != nil
351363 }
352364
@@ -422,13 +434,17 @@ public class UBottomSheetCoordinator {
422434 let oldFrame = container!. frame
423435 var newY = oldFrame. minY
424436
425- if hasExceededTopLimit ( oldFrame. minY + dy , topLimit) {
437+ if hasExceededTopLimit ( oldFrame. minY, topLimit) {
426438 totalTranslationMinY -= dy
439+ totalTranslationMaxY = maxSheetPosition!
427440 newY = dataSource. rubberBandLogicTop ( totalTranslationMinY, topLimit)
428- } else if hasExceededBottomLimit ( oldFrame. minY + dy, bottomLimit) {
441+ } else if hasExceededBottomLimit ( oldFrame. minY, bottomLimit) {
442+ totalTranslationMinY = minSheetPosition!
429443 totalTranslationMaxY += dy
430444 newY = dataSource. rubberBandLogicBottom ( totalTranslationMaxY, bottomLimit)
431445 } else {
446+ totalTranslationMinY = minSheetPosition!
447+ totalTranslationMaxY = maxSheetPosition!
432448 newY += dy
433449 }
434450
@@ -443,10 +459,10 @@ public class UBottomSheetCoordinator {
443459 Pan gesture finish event
444460
445461 - parameter velocity: Pan gesture velocity
462+ - parameter position: new top constraint value
446463 */
447- private func finishDragging( with velocity: CGPoint ) {
448- let top = container!. frame. minY
449- let y = filteredPositions ( velocity, currentPosition: top) . nearest ( to: top)
464+ private func finishDragging( with velocity: CGPoint , position: CGFloat ) {
465+ let y = filteredPositions ( velocity, currentPosition: position) . nearest ( to: position)
450466 endTranslate ( to: y, animated: true )
451467 }
452468
0 commit comments