如何在 SwiftUI 中实现 PageView? [英] How can I implement PageView in SwiftUI?
问题描述
我是 SwiftUI 的新手.我有三个视图,我希望它们在一个 PageView 中.我想通过像页面浏览一样滑动来移动每个视图,我希望小圆点指示我所在的视图.
I am new to SwiftUI. I have three views and I want them in a PageView. I want to move each Views by swipe like a pageview and I want the little dots to indicate in which view I'm in.
推荐答案
SwiftUI 3
在 iOS 15 中引入了新的 TabViewStyle
:CarouselTabViewStyle
(仅限 watchOS).
此外,我们现在可以更轻松地设置样式:
Also, we can now set styles more easily:
.tabViewStyle(.page)
SwiftUI 2
现在在 SwiftUI 2/iOS 14 中有一个与 UIPageViewController
等效的本机.
要创建分页视图,请将 .tabViewStyle
修饰符添加到 TabView
并传递 PageTabViewStyle
.
To create a paged view, add the .tabViewStyle
modifier to TabView
and pass PageTabViewStyle
.
@main
struct TestApp: App {
var body: some Scene {
WindowGroup {
TabView {
FirstView()
SecondView()
ThirdView()
}
.tabViewStyle(PageTabViewStyle())
}
}
}
您还可以控制分页点的显示方式:
You can also control how the paging dots are displayed:
// hide paging dots
.tabViewStyle(PageTabViewStyle(indexDisplayMode: .never))
您可以在此链接中找到更详细的说明:
You can find a more detailed explanation in this link:
TabView {
Group {
FirstView()
SecondView()
ThirdView()
}
.rotationEffect(Angle(degrees: -90))
}
.tabViewStyle(PageTabViewStyle(indexDisplayMode: .never))
.rotationEffect(Angle(degrees: 90))
自定义组件
如果您厌倦了每次创建自己的PageView
时都传递tabViewStyle
:
注意: iOS 14.0 中的 TabView 选择的工作方式不同,这就是我使用两个 Binding
属性的原因:selectionInternal
和 selectionExternal代码>.从 iOS 14.3 开始,它似乎只使用一个
Binding
.但是,您仍然可以从修订历史中访问原始代码.
Note: TabView selection in iOS 14.0 worked differently and that's why I used two Binding
properties: selectionInternal
and selectionExternal
. As of iOS 14.3 it seems to be working with just one Binding
. However, you can still access the original code from the revision history.
struct PageView<SelectionValue, Content>: View where SelectionValue: Hashable, Content: View {
@Binding private var selection: SelectionValue
private let indexDisplayMode: PageTabViewStyle.IndexDisplayMode
private let indexBackgroundDisplayMode: PageIndexViewStyle.BackgroundDisplayMode
private let content: () -> Content
init(
selection: Binding<SelectionValue>,
indexDisplayMode: PageTabViewStyle.IndexDisplayMode = .automatic,
indexBackgroundDisplayMode: PageIndexViewStyle.BackgroundDisplayMode = .automatic,
@ViewBuilder content: @escaping () -> Content
) {
self._selection = selection
self.indexDisplayMode = indexDisplayMode
self.indexBackgroundDisplayMode = indexBackgroundDisplayMode
self.content = content
}
var body: some View {
TabView(selection: $selection) {
content()
}
.tabViewStyle(PageTabViewStyle(indexDisplayMode: indexDisplayMode))
.indexViewStyle(PageIndexViewStyle(backgroundDisplayMode: indexBackgroundDisplayMode))
}
}
extension PageView where SelectionValue == Int {
init(
indexDisplayMode: PageTabViewStyle.IndexDisplayMode = .automatic,
indexBackgroundDisplayMode: PageIndexViewStyle.BackgroundDisplayMode = .automatic,
@ViewBuilder content: @escaping () -> Content
) {
self._selection = .constant(0)
self.indexDisplayMode = indexDisplayMode
self.indexBackgroundDisplayMode = indexBackgroundDisplayMode
self.content = content
}
}
现在你有一个默认的PageView
:
PageView {
FirstView()
SecondView()
ThirdView()
}
可定制:
PageView(indexDisplayMode: .always, indexBackgroundDisplayMode: .always) { ... }
或提供一个selection
:
struct ContentView: View {
@State var selection = 1
var body: some View {
VStack {
Text("Selection: (selection)")
PageView(selection: $selection, indexBackgroundDisplayMode: .always) {
ForEach(0 ..< 3, id: .self) {
Text("Page ($0)")
.tag($0)
}
}
}
}
}
这篇关于如何在 SwiftUI 中实现 PageView?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!