@@ -129,6 +129,7 @@ public class BottomSheetController: UIViewController, Shadowable, TokenizedContr
129129#if DEBUG
130130 bottomSheetView. accessibilityIdentifier = bottomSheetViewAccessibilityIdentifierForState ( )
131131#endif
132+ updateSheetContentOffset ( )
132133 }
133134 }
134135 }
@@ -296,6 +297,19 @@ public class BottomSheetController: UIViewController, Shadowable, TokenizedContr
296297 /// When enabled, users will be able to move the sheet to the hidden state by swiping down.
297298 @objc open var allowsSwipeToHide : Bool = false
298299
300+ /// Indicates whether the resizing handle should overlay the content.
301+ ///
302+ /// The default value is false.
303+ @objc open var shouldResizingHandleOverlayContent : Bool = false {
304+ didSet {
305+ guard shouldResizingHandleOverlayContent != oldValue && isViewLoaded else {
306+ return
307+ }
308+ updateSheetContentOffset ( )
309+ view. setNeedsLayout ( )
310+ }
311+ }
312+
299313 /// Current height of the portion of a collapsed sheet that's in the safe area.
300314 @objc public private( set) var collapsedHeightInSafeArea : CGFloat = 0 {
301315 didSet {
@@ -459,9 +473,9 @@ public class BottomSheetController: UIViewController, Shadowable, TokenizedContr
459473 // |--dimmingView (spans self.view)
460474 // |--bottomSheetView (sheet shadow)
461475 // | |--UIStackView (round corner mask)
462- // | | |--resizingHandleView
463476 // | | |--headerContentView
464477 // | | |--expandedContentView
478+ // | |--resizingHandleView
465479 // |--overflowView
466480 public override func loadView( ) {
467481 view = BottomSheetPassthroughView ( )
@@ -671,7 +685,7 @@ public class BottomSheetController: UIViewController, Shadowable, TokenizedContr
671685 bottomSheetContentView. addGestureRecognizer ( panGestureRecognizer)
672686 panGestureRecognizer. delegate = self
673687
674- let stackView = UIStackView ( arrangedSubviews: [ resizingHandleView ] )
688+ let stackView = UIStackView ( arrangedSubviews: [ ] )
675689 stackView. spacing = 0.0
676690 stackView. axis = . vertical
677691 stackView. translatesAutoresizingMaskIntoConstraints = false
@@ -688,14 +702,20 @@ public class BottomSheetController: UIViewController, Shadowable, TokenizedContr
688702 stackView. addArrangedSubview ( expandedContentView)
689703 bottomSheetContentView. accessibilityElements? . append ( expandedContentView)
690704 bottomSheetContentView. addSubview ( stackView)
705+ bottomSheetContentView. addSubview ( resizingHandleView)
691706
707+ let stackTopConstraint = stackView. topAnchor. constraint ( equalTo: bottomSheetContentView. topAnchor)
692708 NSLayoutConstraint . activate ( [
693- stackView. topAnchor. constraint ( equalTo: bottomSheetContentView. topAnchor) ,
709+ resizingHandleView. topAnchor. constraint ( equalTo: bottomSheetContentView. topAnchor) ,
710+ stackTopConstraint,
694711 stackView. leadingAnchor. constraint ( equalTo: bottomSheetContentView. leadingAnchor) ,
695712 stackView. trailingAnchor. constraint ( equalTo: bottomSheetContentView. trailingAnchor) ,
696- stackView. bottomAnchor. constraint ( equalTo: bottomSheetContentView. bottomAnchor)
713+ stackView. bottomAnchor. constraint ( equalTo: bottomSheetContentView. bottomAnchor) ,
697714 ] )
698715
716+ sheetContentTopConstraint = stackTopConstraint
717+ updateSheetContentOffset ( )
718+
699719 return makeBottomSheetByEmbedding ( contentView: bottomSheetContentView)
700720 } ( )
701721
@@ -794,6 +814,10 @@ public class BottomSheetController: UIViewController, Shadowable, TokenizedContr
794814 }
795815 }
796816
817+ private func updateSheetContentOffset( ) {
818+ sheetContentTopConstraint? . constant = effectiveResizingHandleHeight
819+ }
820+
797821 private func nextExpansionStateForResizingHandleTap( with currentExpansionState: BottomSheetExpansionState ) -> BottomSheetExpansionState ? {
798822 return switch currentExpansionState {
799823 case . collapsed:
@@ -1274,7 +1298,7 @@ public class BottomSheetController: UIViewController, Shadowable, TokenizedContr
12741298 if preferredExpandedContentHeight == 0 {
12751299 height = maxSheetHeight
12761300 } else {
1277- let idealHeight = currentResizingHandleHeight + headerContentHeight + preferredExpandedContentHeight + view. safeAreaInsets. bottom
1301+ let idealHeight = effectiveResizingHandleHeight + headerContentHeight + preferredExpandedContentHeight + view. safeAreaInsets. bottom
12781302 height = min ( maxSheetHeight, idealHeight)
12791303 }
12801304
@@ -1289,9 +1313,9 @@ public class BottomSheetController: UIViewController, Shadowable, TokenizedContr
12891313 if let dynamicHeight = resolvedDynamicSheetHeights? . collapsedHeight, dynamicHeight > 0 {
12901314 safeAreaSheetHeight = dynamicHeight
12911315 } else if collapsedContentHeight > 0 {
1292- safeAreaSheetHeight = collapsedContentHeight + currentResizingHandleHeight
1316+ safeAreaSheetHeight = collapsedContentHeight + effectiveResizingHandleHeight
12931317 } else {
1294- safeAreaSheetHeight = headerContentHeight + currentResizingHandleHeight
1318+ safeAreaSheetHeight = headerContentHeight + effectiveResizingHandleHeight
12951319 }
12961320
12971321 let idealHeight = safeAreaSheetHeight + view. safeAreaInsets. bottom
@@ -1329,8 +1353,12 @@ public class BottomSheetController: UIViewController, Shadowable, TokenizedContr
13291353 // Do not access directly. Use `resolvedDynamicSheetHeights` instead which wraps this cache.
13301354 private var cachedResolvedDynamicSheetHeights : DynamicHeightResolutionResult ?
13311355
1332- private var currentResizingHandleHeight : CGFloat {
1333- ( isExpandable ? ResizingHandleView . height : 0.0 )
1356+ // Effective height of the resizing handle for layout purposes.
1357+ // Accounts for:
1358+ // - when the sheet is not expandable (resizing handle doesn't show, so 0 height)
1359+ // - when the resizing handle overlaps content - effective height is also 0
1360+ private var effectiveResizingHandleHeight : CGFloat {
1361+ ( isExpandable && !shouldResizingHandleOverlayContent ? ResizingHandleView . height : 0.0 )
13341362 }
13351363
13361364 private lazy var panGestureRecognizer : UIPanGestureRecognizer = UIPanGestureRecognizer ( target: self , action: #selector( handlePan) )
@@ -1365,6 +1393,8 @@ public class BottomSheetController: UIViewController, Shadowable, TokenizedContr
13651393
13661394 private let style : BottomSheetControllerStyle
13671395
1396+ private var sheetContentTopConstraint : NSLayoutConstraint ?
1397+
13681398 // Dynamic heights, resolved with the corresponding context.
13691399 private typealias DynamicHeightResolutionResult = ( context: ContentHeightResolutionContext , collapsedHeight: CGFloat ? , partialHeight: CGFloat ? )
13701400
0 commit comments