有没有办法在 SwiftUI 中制作分页 ScrollView? [英] Is there any way to make a paged ScrollView in SwiftUI?

查看:45
本文介绍了有没有办法在 SwiftUI 中制作分页 ScrollView?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在浏览每个测试版的文档,但还没有看到制作传统分页 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆