Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
91 changes: 53 additions & 38 deletions ios/TrueSheetView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -418,50 +418,65 @@ class TrueSheetView: UIView, RCTInvalidating, TrueSheetViewControllerDelegate {
promise.resolve(nil)
}
}

private func topPresenter() -> UIViewController? {
reactViewController()?.topMostPresenter
}

func present(at index: Int, promise: Promise?, animated: Bool = true) {
let rvc = reactViewController()
func present(at index: Int, promise: Promise?, animated: Bool = true) {
guard let presenter = topPresenter() else {
promise?.reject(message: "No react view controller present.")
return
}

guard let rvc else {
promise?.reject(message: "No react view controller present.")
return
}
guard viewController.sizes.indices.contains(index) else {
promise?.reject(message: "Size at \(index) is not configured.")
return
}

guard viewController.sizes.indices.contains(index) else {
promise?.reject(message: "Size at \(index) is not configured.")
return
}
if isPresented {
if #available(iOS 15.0, *) {
withPresentedSheet { sheet in
sheet.selectedDetentIdentifier = viewController.detentIdentifierForIndex(index)
viewControllerDidChangeSize(self.viewController.currentSizeInfo)
promise?.resolve(nil)
}
} else {
viewControllerDidChangeSize(viewController.currentSizeInfo)
promise?.resolve(nil)
}
return
}

viewController.prepareForPresentation(at: index) { [weak self] in
guard let self = self else { return }

if isPresented {
if #available(iOS 15.0, *) {
withPresentedSheet { sheet in
sheet.selectedDetentIdentifier = viewController.detentIdentifierForIndex(index)
self.activeIndex = index
self.isPresented = true

// Trigger onSizeChange event when size is changed while presenting
viewControllerDidChangeSize(self.viewController.currentSizeInfo)
promise?.resolve(nil)
presenter.present(self.viewController, animated: animated) {
if #available(iOS 15.0, *) {
self.viewController.observeDrag()
}

let data = self.sizeInfoData(from: self.viewController.currentSizeInfo)
self.dispatchEvent(name: "onPresent", block: self.onPresent, data: data)
promise?.resolve(nil)
}
}
} else {
// Trigger onSizeChange event when size is changed while presenting
viewControllerDidChangeSize(viewController.currentSizeInfo)
promise?.resolve(nil)
}
} else {
viewController.prepareForPresentation(at: index) {
// Keep track of the active index
self.activeIndex = index
self.isPresented = true

rvc.present(self.viewController, animated: animated) {
if #available(iOS 15.0, *) {
self.viewController.observeDrag()
}

let data = self.sizeInfoData(from: self.viewController.currentSizeInfo)
self.dispatchEvent(name: "onPresent", block: self.onPresent, data: data)
promise?.resolve(nil)
}
}

extension UIViewController {
/// Returns the view controller that should receive a new modal presentation.
/// Walks the hierarchy: RN root → UINavigationController → presented VCs.
var topMostPresenter: UIViewController {
var top = self
while let presented = top.presentedViewController {
top = presented
}
}
// If we are inside a UINavigationController, present from the navigation controller
// so the sheet appears over the whole navigation stack.
return top.navigationController ?? top
}
}
}