Skip to content

Instantly share code, notes, and snippets.

@mishimay
Last active September 18, 2022 10:35
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mishimay/b823280bd91d16474362376029321752 to your computer and use it in GitHub Desktop.
Save mishimay/b823280bd91d16474362376029321752 to your computer and use it in GitHub Desktop.
struct PagingScrollView<Content: View>: UIViewRepresentable {
let size: CGSize
@Binding var contentOffset: CGPoint
@ViewBuilder let content: () -> Content
class Coordinator: NSObject, UIScrollViewDelegate {
var hostingController: UIHostingController<Content>?
var contentOffsetChanged: ((CGPoint) -> Void)?
func scrollViewDidScroll(_ scrollView: UIScrollView) {
contentOffsetChanged?(scrollView.contentOffset)
}
}
func makeCoordinator() -> Coordinator {
Coordinator()
}
func makeUIView(context: Context) -> UIScrollView {
let view = UIScrollView()
view.delegate = context.coordinator
view.isPagingEnabled = true
view.showsHorizontalScrollIndicator = false
view.showsVerticalScrollIndicator = false
view.contentInsetAdjustmentBehavior = .never
let hostingController = UIHostingController(rootView: content())
context.coordinator.hostingController = hostingController
let contentView = hostingController.view ?? UIView()
contentView.backgroundColor = .clear
view.addSubview(contentView)
context.coordinator.contentOffsetChanged = { contentOffset in
DispatchQueue.main.async {
self.contentOffset = contentOffset
}
}
NotificationCenter.default.addObserver(forName: UIDevice.orientationDidChangeNotification, object: nil, queue: .main) { _ in
view.contentOffset = .zero
}
return view
}
func updateUIView(_ uiView: UIScrollView, context: Context) {
context.coordinator.hostingController?.rootView = content()
uiView.contentSize = size
context.coordinator.hostingController?.view.frame = CGRect(origin: .zero, size: size)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment