我是 SwiftUI 新手。我有三个 View ,我希望它们位于页面 View 中。我想像页面浏览一样通过滑动来移动每个 View ,并且我希望小点指示我所在的 View 。
最佳答案
iOS 15+
在 iOS 15 中引入了新的 TabViewStyle
:CarouselTabViewStyle
(仅限 watchOS)。
此外,我们现在可以更轻松地设置样式:
.tabViewStyle(.page)
iOS 14+
SwiftUI 2/iOS 14 中现在有一个相当于 UIPageViewController
的原生版本。
要创建分页 View ,请将 .tabViewStyle
修饰符添加到 TabView
并传递 PageTabViewStyle
。
@main
struct TestApp: App {
var body: some Scene {
WindowGroup {
TabView {
FirstView()
SecondView()
ThirdView()
}
.tabViewStyle(PageTabViewStyle())
}
}
}
您还可以控制分页点的显示方式:
// hide paging dots
.tabViewStyle(PageTabViewStyle(indexDisplayMode: .never))
您可以在此链接中找到更详细的说明:
<小时/>垂直变体
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
。但是,您仍然可以从修订历史记录中访问原始代码。
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) { ... }
或提供选择
:
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)
}
}
}
}
}
关于ios - 如何在 SwiftUI 中实现 PageView?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58388071/