我是SwiftUI的新手.我有三个视图,我希望它们在页面视图中.我想通过像页面视图一样滑动来移动每个视图,我想让小点指示我在哪个视图中.

推荐答案

迅捷3

iOS 15引入了一个新的TabViewStyle:CarouselTabViewStyle(watchOS only).

此外,我们现在可以更轻松地设置样式:

.tabViewStyle(.page)

迅捷2

在迅捷2/iOS 14中,现在有了一个UIPageViewController的本地类似功能.

要创建分页视图,请将.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))

自定义组件

如果你厌倦了每次都通过tabViewStyle分,你可以创建自己的PageView分:

Note:在iOS 14.0中,TabView Select 的工作方式不同,这就是为什么我使用了两个Binding属性:selectionInternalselectionExternal.从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) { ... }

或配备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)
                }
            }
        }
    }
}

Swift相关问答推荐

在swift静态var扩展中,如何或可以访问和返回具体类?

计算Vision OS相机与Vision OS中3D模型之间的距离

什么是Swift Concurrency中任务组的正常退出

动画过程中的SwiftUI重绘视图

SwiftUI:使视图B与视图A具有相同宽度的视图A更改比率?

Swift-Can无法在AudioKit中找出简单的麦克风效果-文件链

为SwiftUI文本视图提供固定宽度,并仅在文本换行时使文本视图底部增大

为什么枚举上的.allCases.forEach不是循环(继续和中断不起作用)?

SwiftUI 组合问题:通过 AppEventsManager 在 ViewModel 之间共享数据

有没有一种方法可以访问封闭实例ObservableObject以从属性包装器中的任何位置调用objectWillChange.send()

如何有条件地依赖桌面与 iOS 的系统库?

Swift:withCheckedContinuation 和 Dispatch QoSClass

`@available` 属性在 macOS 版本上被错误地限制

我们如何显示关于 UITextField 是 xCode Swift 的建议?

在 Swift 4 中,如何删除基于块的 KVO 观察者?

为什么'nil' 与 Swift 3 中的 'UnsafePointer' 不兼容?

Swift 中的 CommonHMAC

使用相机进行人脸检测

Swift 中的可选数组与空数组

如何使用 Swift 将文本文件逐行加载到数组中?