Skip to content

Commit 98f0f2b

Browse files
veronicasalasVeronica SalasvsalasLukas Capkovic
authored
[fluentui-apple] Have resizingHandleView overlap content in BottomSheetController (#2236)
* add shouldGrabberOverlayContent option * remove constants * renaming * fixing nit * make resizingHandleView subview of bottomSheetContentView * remove toggleResizingViewOverlayContent * Resizing handle overlay updates --------- Co-authored-by: Veronica Salas <veronicasalas@Veronicas-MacBook-Pro.local> Co-authored-by: vsalas <vsalas@microsoft.com> Co-authored-by: Lukas Capkovic <lucapkov@microsoft.com>
1 parent 6517426 commit 98f0f2b

File tree

2 files changed

+48
-10
lines changed

2 files changed

+48
-10
lines changed

Demos/FluentUIDemo_iOS/FluentUI.Demo/Demos/BottomSheetDemoController.swift

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,10 @@ class BottomSheetDemoController: DemoController {
103103
bottomSheetViewController?.preferredWidth = sender.isOn ? 400 : 0
104104
}
105105

106+
@objc private func toggleResizingHandleOverlayContent(_ sender: BooleanCell) {
107+
bottomSheetViewController?.shouldResizingHandleOverlayContent = sender.isOn
108+
}
109+
106110
@objc private func showTransientSheet() {
107111
let hostingVC = UIHostingController(rootView: BottomSheetDemoListContentView())
108112

@@ -275,7 +279,11 @@ class BottomSheetDemoController: DemoController {
275279
DemoItem(title: "Set preferred width to 400",
276280
type: .boolean,
277281
action: #selector(togglePreferredWidth),
278-
isOn: bottomSheetViewController?.preferredWidth == 400)
282+
isOn: bottomSheetViewController?.preferredWidth == 400),
283+
DemoItem(title: "Resizing handle overlaps content",
284+
type: .boolean,
285+
action: #selector(toggleResizingHandleOverlayContent),
286+
isOn: bottomSheetViewController?.shouldResizingHandleOverlayContent ?? false)
279287
],
280288
[
281289
DemoItem(title: "Show transient sheet", type: .action, action: #selector(showTransientSheet))

Sources/FluentUI_iOS/Components/BottomSheet/BottomSheetController.swift

Lines changed: 39 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)