Last active
April 8, 2025 07:26
-
-
Save watabee/fa4ce518c309aa1dbabf3e748a42414b to your computer and use it in GitHub Desktop.
Workaround for using SwiftUI inside Compose Multiplatform
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
struct ContentView: UIViewControllerRepresentable { | |
func makeUIViewController(context: Context) -> UIViewController { | |
return MainViewControllerKt.MainViewController { | |
let swiftUIView = ScrollView { | |
LazyVStack { | |
ForEach(0..<100, id: \.self) { index in | |
VStack { | |
Text("item \(index + 1)") | |
.padding(16) | |
Divider() | |
} | |
} | |
} | |
} | |
.frame(maxWidth: .infinity, maxHeight: .infinity) | |
return ResolveGestureViewController(rootView: swiftUIView) | |
} | |
} | |
func updateUIViewController(_ uiViewController: UIViewController, context: Context) { | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Called from iOS | |
@Suppress("unused") | |
fun MainViewController( | |
createViewController: () -> UIViewController, | |
) = ComposeUIViewController { | |
Surface { | |
UIKitViewController( | |
factory = createViewController, | |
modifier = Modifier.fillMaxSize(), | |
) | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class ResolveGestureViewController<Content: View>: UIHostingController<Content>, UIGestureRecognizerDelegate { | |
override func willMove(toParent parent: UIViewController?) { | |
super.willMove(toParent: parent) | |
if let parent { | |
parent.view.getAllSubviews().forEach { composeView in | |
composeView.gestureRecognizers?.forEach { gestureRecognizer in | |
if String(describing: type(of: gestureRecognizer)).contains("CMPGestureRecognizer") { | |
gestureRecognizer.delegate = self | |
} | |
} | |
} | |
} | |
} | |
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRequireFailureOf otherGestureRecognizer: UIGestureRecognizer) -> Bool { | |
// Returning true will give priority to otherGestureRecognizer's gestures, effectively lowering the priority of CMPGestureRecognizer. | |
return true | |
} | |
} | |
extension UIView { | |
public func getAllSubviews() -> [UIView] { | |
subviews + subviews.flatMap { $0.getAllSubviews() } | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment