As someone who learned Swift via SwiftUI, UIKit is completely alien to me, so I apologize if this is actually a very simple issue.
I have a Messages extension that includes a sticker browser within it. In this extension, the MSMessagesAppViewController hosts a SwiftUI View, which in turn hosts a UIViewRepresentable version of MSStickerBrowserView.
The whole Messages App sheet moves with an upward drag, and can switch to its expanded mode, whenever the browser is scrolled to the top (first sticker is at top left), but it doesn't budge when the browser is scrolled to the other end when it should allow the sheet to move upward with the drag.
It seems something is reversed within the gesture priority management that allows a sheet to be moved in the appropriate direction when a contained scrollview is at the appropriate end.
Things I've tried while reaching a diagnosis include:
- Limiting the presentation style to compact (the modal still moves, but never succeeds in changing)
- Adding competing highPriorityGestures in the SwiftUI view, set at various locations
- Inserting a rectangle with allowsHitTesting(false) beneath the browser
- Changing firstResponder statuses for all relevant views
- Changing GestureResponder priorities (there are no gesture responders in all views examined)
Things I've considered but don't have the technical skills to implement:
- Have the view scroll a little downwards programmatically (like what can be done via ScrollViewReader in SwiftUI), but I have no idea how this can be done via MSStickerBrowserView or UIKit in general.
- Maybe the MSStickerBrowserView thinks its always in the expanded state (when the sheet is expanded, the end-drags work fine). If this is the case, if there's a way to either fix this misconception (via controller's didTransition) or do away with end drags in general, the problem should go away.
Any pointers would be greatly appreciated!
One solution is to stick everything in a SwiftUI TabView (with the .page style). You should be able to use either MSStickerBrowserView or MSStickerViews wrapped in a UIViewRepresentable
struct Playground: View {
@State private var isSheetPresented = true
@State private var detent = PresentationDetent.fraction(1/3)
var body: some View {
Rectangle()
.fill(Color(.systemGray5))
.sheet(isPresented: $isSheetPresented) {
VStack {
Text("ScrollView-in-Sheet Experiment")
.padding()
TabView {
ScrollView {
VStack(spacing: 0) {
ForEach(0...100, id: \.self) { e in
Rectangle()
.fill(.white)
.border(.gray, width: 0.3)
.frame(width: 50)
.overlay { Text(e.description) }
}
}
}
}
.tabViewStyle(.page(indexDisplayMode: .never))
}
.background { Color(.systemGray6) }
.presentationDetents([.large, .fraction(1/3)], selection: $detent)
}
}
}