You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在watchOS中用SwiftUI实现类系统健身应用的垂直滚动页面

实现类似Apple Watch健身应用的垂直滚动页面

我想要实现一个类似系统健身应用的垂直滚动页面,效果如下:
系统健身应用垂直滚动页面效果

目前我通过以下代码实现了类似效果:

TabView {
  page1
    .rotationEffect(.degrees(90))
  page2
    .rotationEffect(.degrees(90))
}.tabViewStyle(.page(indexDisplayMode: .automatic))
.rotationEffect(.degrees(-90))

但该效果不如系统健身应用理想,系统应用支持数码表冠(Digital Crown)操作、动态显示指示器以及自定义颜色。当前实现效果如下:
当前实现效果

请问该如何实现符合预期的垂直滚动效果?


解决方案:原生垂直分页ScrollView + 数码表冠绑定

Apple Watch健身应用并未采用旋转TabView的hack方式,而是基于原生垂直分页滚动实现,以下是完整实现方案:

  1. 构建原生垂直分页滚动
    使用ScrollView(.vertical)配合分页行为修饰符,替代旋转TabView的方案,iOS17+/watchOS10+可直接用原生分页API:
ScrollView(.vertical) {
    VStack(spacing: 0) {
        page1
            .frame(height: WKInterfaceDevice.current().screenBounds.height)
        page2
            .frame(height: WKInterfaceDevice.current().screenBounds.height)
        // 按需添加更多页面
    }
}
.scrollTargetBehavior(.paging) // 原生分页行为
.scrollIndicators(.hidden) // 隐藏系统滚动条

如果需要兼容旧版本,可替换为.pageSnap()修饰符。

  1. 绑定数码表冠控制滚动
    通过ScrollViewReader结合数码表冠绑定,实现精准的页面切换:
@State private var currentPage = 0
private let pageCount = 2

var body: some View {
    ScrollViewReader { proxy in
        VStack(spacing: 0) {
            ScrollView(.vertical) {
                VStack(spacing: 0) {
                    page1.id(0)
                        .frame(height: WKInterfaceDevice.current().screenBounds.height)
                    page2.id(1)
                        .frame(height: WKInterfaceDevice.current().screenBounds.height)
                }
                .scrollTargetLayout()
            }
            .scrollTargetBehavior(.paging)
            .scrollIndicators(.hidden)
            
            // 自定义分页指示器
            HStack(spacing: 6) {
                ForEach(0..<pageCount, id: \.self) { index in
                    Circle()
                        .frame(width: index == currentPage ? 8 : 4, height: index == currentPage ? 8 : 4)
                        .foregroundColor(index == currentPage ? .green : .gray.opacity(0.5))
                        .animation(.easeInOut, value: currentPage)
                }
            }
            .padding(.bottom, 10)
        }
        .focusable()
        .digitalCrownRotation($currentPage, from: 0, through: pageCount - 1, by: 1, sensitivity: .high)
        .onChange(of: currentPage) { _, newValue in
            withAnimation {
                proxy.scrollTo(newValue, anchor: .top)
            }
        }
    }
}
  1. 关键细节优化
  • 每个页面强制设置为屏幕高度,确保分页精准
  • 数码表冠的sensitivity参数设为.high,适配快速切换场景
  • 自定义指示器通过currentPage状态实现动态大小和颜色变化,完全匹配健身应用风格

内容的提问来源于stack exchange,提问作者Haozes

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 18:55:18