有没有办法在 SwiftUI 中制作分页 ScrollView? [英] Is there any way to make a paged ScrollView in SwiftUI?
问题描述
我一直在浏览每个测试版的文档,但还没有看到制作传统分页 ScrollView 的方法.我不熟悉 AppKit,所以我想知道这在 SwiftUI 中是否不存在,因为它主要是一个 UIKit 构造.无论如何,有没有人有这样的例子,或者谁能告诉我这绝对是不可能的,所以我可以停止寻找并自己动手?
I've been looking through the docs with each beta but haven't seen a way to make a traditional paged ScrollView. I'm not familiar with AppKit so I am wondering if this doesn't exist in SwiftUI because it's primarily a UIKit construct. Anyway, does anyone have an example of this, or can anyone tell me it's definitely impossible so I can stop looking and roll my own?
推荐答案
从 Beta 3 开始,没有用于分页的本机 SwiftUI API.我已经提交了反馈并建议您也这样做.他们将 ScrollView
API 从 Beta 2 更改为 Beta 3,看到进一步更新我不会感到惊讶.
As of Beta 3 there is no native SwiftUI API for paging. I've filed feedback and recommend you do the same. They changed the ScrollView
API from Beta 2 to Beta 3 and I wouldn't be surprised to see a further update.
现在可以包装 UIScrollView
以提供此功能.不幸的是,您必须将 UIScrollView 包装在 UIViewController
中,后者进一步包装在 UIViewControllerRepresentable
中以支持 SwiftUI 内容.
It is possible to wrap a UIScrollView
in order to provide this functionality now. Unfortunately, you must wrap the UIScrollView in a UIViewController
, which is further wrapped in UIViewControllerRepresentable
in order to support SwiftUI content.
class UIScrollViewViewController: UIViewController {
lazy var scrollView: UIScrollView = {
let v = UIScrollView()
v.isPagingEnabled = true
return v
}()
var hostingController: UIHostingController<AnyView> = UIHostingController(rootView: AnyView(EmptyView()))
override func viewDidLoad() {
super.viewDidLoad()
self.view.addSubview(self.scrollView)
self.pinEdges(of: self.scrollView, to: self.view)
self.hostingController.willMove(toParent: self)
self.scrollView.addSubview(self.hostingController.view)
self.pinEdges(of: self.hostingController.view, to: self.scrollView)
self.hostingController.didMove(toParent: self)
}
func pinEdges(of viewA: UIView, to viewB: UIView) {
viewA.translatesAutoresizingMaskIntoConstraints = false
viewB.addConstraints([
viewA.leadingAnchor.constraint(equalTo: viewB.leadingAnchor),
viewA.trailingAnchor.constraint(equalTo: viewB.trailingAnchor),
viewA.topAnchor.constraint(equalTo: viewB.topAnchor),
viewA.bottomAnchor.constraint(equalTo: viewB.bottomAnchor),
])
}
}
struct UIScrollViewWrapper<Content: View>: UIViewControllerRepresentable {
var content: () -> Content
init(@ViewBuilder content: @escaping () -> Content) {
self.content = content
}
func makeUIViewController(context: Context) -> UIScrollViewViewController {
let vc = UIScrollViewViewController()
vc.hostingController.rootView = AnyView(self.content())
return vc
}
func updateUIViewController(_ viewController: UIScrollViewViewController, context: Context) {
viewController.hostingController.rootView = AnyView(self.content())
}
}
然后使用它:
var body: some View {
GeometryReader { proxy in
UIScrollViewWrapper {
VStack {
ForEach(0..<1000) { _ in
Text("Hello world")
}
}
.frame(width: proxy.size.width) // This ensures the content uses the available width, otherwise it will be pinned to the left
}
}
}
这篇关于有没有办法在 SwiftUI 中制作分页 ScrollView?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!