Bra*_*rad 2 uiscrollview swiftui
我一直在浏览每个Beta版本的文档,但没有找到制作传统的分页ScrollView的方法。我对AppKit不熟悉,所以我想知道SwiftUI中是否不存在此控件,因为它主要是UIKit构造。无论如何,有没有人举这个例子,或者有人可以告诉我这绝对是不可能的,所以我可以停止寻找自己的作品了吗?
小智 11
您现在可以使用 TabView 并将 .tabViewStyle 设置为 PageTabViewStyle()
TabView {
View1()
View2()
View3()
}
.tabViewStyle(PageTabViewStyle())
Run Code Online (Sandbox Code Playgroud)
苹果的官方教程以这个为例。我发现它很容易遵循并且适合我的情况。我真的建议您检查一下并尝试了解如何与 UIKit 交互。由于 SwiftUI 还很年轻,因此目前不会涵盖 UIKit 中的所有功能。与 UIKit 接口应该可以满足大多数(如果不是全部)需求。
https://developer.apple.com/tutorials/swiftui/interface-with-uikit
从Beta 3开始,没有用于页面调度的本机SwiftUI API。我已提出反馈,建议您也这样做。他们将ScrollViewAPI从Beta 2 更改为Beta 3,看到进一步的更新我不会感到惊讶。
现在可以包装a UIScrollView以便提供此功能。不幸的是,您必须将UIScrollView包装在中UIViewController,进一步包装UIViewControllerRepresentable以支持SwiftUI内容。
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())
}
}
Run Code Online (Sandbox Code Playgroud)
然后使用它:
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
}
}
}
Run Code Online (Sandbox Code Playgroud)
您可以使用这样的自定义修饰符:
struct ScrollViewPagingModifier: ViewModifier {
func body(content: Content) -> some View {
content
.onAppear {
UIScrollView.appearance().isPagingEnabled = true
}
.onDisappear {
UIScrollView.appearance().isPagingEnabled = false
}
}
}
extension ScrollView {
func isPagingEnabled() -> some View {
modifier(ScrollViewPagingModifier())
}
}
Run Code Online (Sandbox Code Playgroud)
iOS 17 中正式支持分页ScrollView,并在 WWDC 2023 上引入。
您可以使用以 a 作为参数的newscrollTargetBehavior修饰符(文档ScrollTargetBehavior) 。出于分页目的,请传递它.paging。
他们在“超越滚动视图”会话中详细介绍了其工作原理。
不确定这是否对您的问题有帮助,但目前,当 Apple 正在努力在 SwiftUI 中添加分页视图时,我编写了一个实用程序库,在使用UIPageViewController隐藏的引擎盖时为您提供 SwiftUI 感觉。
你可以这样使用它:
Pages {
Text("Page 1")
Text("Page 2")
Text("Page 3")
Text("Page 4")
}
Run Code Online (Sandbox Code Playgroud)
或者,如果您的应用程序中有一个模型列表,您可以像这样使用它:
struct Car {
var model: String
}
let cars = [Car(model: "Ford"), Car(model: "Ferrari")]
ModelPages(cars) { index, car in
Text("The \(index) car is a \(car.model)")
.padding(50)
.foregroundColor(.white)
.background(Color.blue)
.cornerRadius(10)
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1926 次 |
| 最近记录: |