Skip to content

Commit

Permalink
fix(ios): correct size when changing size programmatically
Browse files Browse the repository at this point in the history
  • Loading branch information
lodev09 committed Feb 9, 2025
1 parent 936cbd6 commit d94ca87
Show file tree
Hide file tree
Showing 3 changed files with 104 additions and 75 deletions.
12 changes: 4 additions & 8 deletions example/src/screens/MapScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,7 @@ export const MapScreen = () => {
})),
]

const handlePresent = (sizeInfo: SizeInfo) => {
buttonY.value = withSpring(-sizeInfo.value, SPRING_CONFIG)
}

const handleSizeChange = (sizeInfo: SizeInfo) => {
const animateButton = (sizeInfo: SizeInfo) => {
buttonY.value = withSpring(-sizeInfo.value, SPRING_CONFIG)
}

Expand Down Expand Up @@ -96,9 +92,9 @@ export const MapScreen = () => {
cornerRadius={12}
initialIndex={1}
onDragChange={dragChangeHandler}
onPresent={(e) => handlePresent(e.nativeEvent)}
onSizeChange={(e) => handleSizeChange(e.nativeEvent)}
// onDragEnd={(e) => handleSizeChange(e.nativeEvent)}
onPresent={(e) => animateButton(e.nativeEvent)}
onSizeChange={(e) => animateButton(e.nativeEvent)}
onDragEnd={(e) => animateButton(e.nativeEvent)}
// initialIndexAnimated={false}
onMount={() => {
// sheetRef.current?.present(1)
Expand Down
63 changes: 42 additions & 21 deletions ios/TrueSheetView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -230,13 +230,28 @@ class TrueSheetView: UIView, RCTInvalidating, TrueSheetViewControllerDelegate {
}

viewController.maxHeight = maxHeight
configurePresentedSheet()

if #available(iOS 15.0, *) {
withPresentedSheet { _ in
viewController.setupSizes()
}
}
}

@objc
func setContentHeight(_ height: NSNumber) {
viewController.setContentHeight(CGFloat(height.floatValue))
configurePresentedSheet()
let contentHeight = CGFloat(height.floatValue)
guard viewController.contentHeight != contentHeight else {
return
}

viewController.contentHeight = contentHeight

if #available(iOS 15.0, *) {
withPresentedSheet { _ in
viewController.setupSizes()
}
}
}

@objc
Expand All @@ -257,13 +272,22 @@ class TrueSheetView: UIView, RCTInvalidating, TrueSheetViewControllerDelegate {
footerViewHeightConstraint.constant = 0
}

configurePresentedSheet()
if #available(iOS 15.0, *) {
withPresentedSheet { _ in
viewController.setupSizes()
}
}
}

@objc
func setSizes(_ sizes: [Any]) {
viewController.sizes = Array(sizes.prefix(3))
configurePresentedSheet()

if #available(iOS 15.0, *) {
withPresentedSheet { _ in
viewController.setupSizes()
}
}
}

@objc
Expand Down Expand Up @@ -319,8 +343,8 @@ class TrueSheetView: UIView, RCTInvalidating, TrueSheetViewControllerDelegate {
viewController.dimmed = dimmed

if #available(iOS 15.0, *) {
withPresentedSheet { sheet in
viewController.setupDimmedBackground(for: sheet)
withPresentedSheet { _ in
viewController.setupDimmedBackground()
}
}
}
Expand All @@ -334,8 +358,8 @@ class TrueSheetView: UIView, RCTInvalidating, TrueSheetViewControllerDelegate {
viewController.dimmedIndex = index.intValue

if #available(iOS 15.0, *) {
withPresentedSheet { sheet in
viewController.setupDimmedBackground(for: sheet)
withPresentedSheet { _ in
viewController.setupDimmedBackground()
}
}
}
Expand Down Expand Up @@ -367,13 +391,6 @@ class TrueSheetView: UIView, RCTInvalidating, TrueSheetViewControllerDelegate {
}
}

/// Fully reconfigure the sheet. Use during size prop changes.
func configurePresentedSheet() {
if isPresented {
viewController.configureSheet(at: activeIndex ?? 0, nil)
}
}

func setupScrollable() {
guard let contentView, let containerView, let scrollableTag else {
return
Expand Down Expand Up @@ -416,12 +433,16 @@ class TrueSheetView: UIView, RCTInvalidating, TrueSheetViewControllerDelegate {
return
}

viewController.configureSheet(at: index) {
// Trigger onSizeChange event when size is changed while presenting
if self.isPresented {
self.viewControllerDidChangeSize(self.viewController.currentSizeInfo)
if isPresented {
withPresentedSheet { sheet in
sheet.selectedDetentIdentifier = viewController.detentIdentifierForIndex(index)

// Trigger onSizeChange event when size is changed while presenting
viewControllerDidChangeSize(self.viewController.currentSizeInfo)
promise?.resolve(nil)
} else {
}
} else {
viewController.prepareForPresentation(at: index) {
// Keep track of the active index
self.activeIndex = index
self.isPresented = true
Expand Down
104 changes: 58 additions & 46 deletions ios/TrueSheetViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -160,17 +160,6 @@ class TrueSheetViewController: UIViewController, UISheetPresentationControllerDe
}
}

func setContentHeight(_ height: CGFloat) {
// Exclude bottom safe area for consistency with a Scrollable content
let adjustedContentHeight = height - bottomInset

guard contentHeight != adjustedContentHeight else {
return
}

contentHeight = adjustedContentHeight
}

/// Setup background. Supports color or blur effect.
/// Can only use one or the other.
func setupBackground() {
Expand All @@ -186,7 +175,11 @@ class TrueSheetViewController: UIViewController, UISheetPresentationControllerDe
/// Setup dimmed sheet.
/// `dimmedIndex` will further customize the dimming behavior.
@available(iOS 15.0, *)
func setupDimmedBackground(for sheet: UISheetPresentationController) {
func setupDimmedBackground() {
guard let sheet = sheetPresentationController else {
return
}

if dimmed, dimmedIndex == 0 {
sheet.largestUndimmedDetentIdentifier = nil
} else {
Expand All @@ -202,6 +195,50 @@ class TrueSheetViewController: UIViewController, UISheetPresentationControllerDe
}
}

/// Setup sheet detents by sizes.
@available(iOS 15.0, *)
func setupSizes() {
guard let sheet = sheetPresentationController else {
return
}

// Configure detents
detentValues = [:]
var detents: [UISheetPresentationController.Detent] = []

for (index, size) in sizes.enumerated() {
// Exclude bottom safe area for consistency with a Scrollable content
let adjustedContentHeight = contentHeight - bottomInset
let detent = detentFor(size, with: adjustedContentHeight + footerHeight, with: maxHeight) { id, value in
self.detentValues[id] = SizeInfo(index: index, value: value)
}

detents.append(detent)
}

sheet.detents = detents
}

/// Get the detent identifier for a given index
@available(iOS 15.0, *)
func detentIdentifierForIndex(_ index: Int) -> UISheetPresentationController.Detent.Identifier {
guard let sheet = sheetPresentationController else {
return .medium
}

var identifier = UISheetPresentationController.Detent.Identifier.medium
if sheet.detents.indices.contains(index) {
let detent = sheet.detents[index]
if #available(iOS 16.0, *) {
identifier = detent.identifier
} else if detent == .large() {
identifier = .large
}
}

return identifier
}

/// Observe while the sheet is being dragged.
@available(iOS 15.0, *)
func observeDrag() {
Expand All @@ -218,46 +255,21 @@ class TrueSheetViewController: UIViewController, UISheetPresentationControllerDe
}

/// Prepares the view controller for sheet presentation
func configureSheet(at index: Int = 0, _ completion: (() -> Void)?) {
func prepareForPresentation(at index: Int = 0, _ completion: (() -> Void)?) {
guard #available(iOS 15.0, *), let sheet = sheetPresentationController else {
completion?()
return
}

detentValues = [:]

var detents: [UISheetPresentationController.Detent] = []

for (index, size) in sizes.enumerated() {
let detent = detentFor(size, with: contentHeight + footerHeight, with: maxHeight) { id, value in
self.detentValues[id] = SizeInfo(index: index, value: value)
}

detents.append(detent)
}

sheet.animateChanges {
sheet.detents = detents
sheet.prefersEdgeAttachedInCompactHeight = true
sheet.prefersGrabberVisible = grabber
sheet.preferredCornerRadius = cornerRadius
sheet.delegate = self

var identifier: UISheetPresentationController.Detent.Identifier = .medium

if sheet.detents.indices.contains(index) {
let detent = sheet.detents[index]
if #available(iOS 16.0, *) {
identifier = detent.identifier
} else if detent == .large() {
identifier = .large
}
}
setupSizes()
setupDimmedBackground()

setupDimmedBackground(for: sheet)
sheet.delegate = self
sheet.prefersEdgeAttachedInCompactHeight = true
sheet.prefersGrabberVisible = grabber
sheet.preferredCornerRadius = cornerRadius
sheet.selectedDetentIdentifier = detentIdentifierForIndex(index)

sheet.selectedDetentIdentifier = identifier
completion?()
}
completion?()
}
}

0 comments on commit d94ca87

Please sign in to comment.