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

Vision Pro Curve View固定分页集合设置及SwiftUI渐变高度视图实现

1. 在Vision Pro的Curve View中设置带有固定分页的集合

在VisionOS中实现Curve View结合固定分页的集合,推荐用SwiftUI结合ScrollView的分页行为来实现,步骤如下:

  • 使用ScrollView(.horizontal)承载集合内容,通过.scrollTargetBehavior(.paging)开启固定分页。
  • 将集合内容嵌套进CurvedView,调整曲率参数让项在曲线上均匀分布,保证分页切换时刚好展示完整的一组内容。

示例代码:

import SwiftUI

struct CurvedPagingCollection: View {
    let items = (1...8).map { "Card \($0)" }
    
    var body: some View {
        ScrollView(.horizontal) {
            HStack(spacing: 24) {
                ForEach(items, id: \.self) { item in
                    Text(item)
                        .frame(width: 220, height: 320)
                        .background(Color.blue.opacity(0.6))
                        .cornerRadius(16)
                        .shadow(radius: 8)
                }
            }
            .padding(.horizontal, 40)
        }
        .scrollTargetBehavior(.paging)
        .curvedViewStyle(.continuous)
        .curvature(0.35) // 按需调整曲率值,控制弯曲程度
        .frame(height: 380)
    }
}

如果需要更精准的分页边界控制,可以自定义ScrollTargetLayout,指定每个分页的起始和结束位置,适配Curve View的曲率特性。


2. SwiftUI中实现中间视图正常高度、两侧向中间高度渐变的效果

该效果可以通过GeometryReader获取视图位置参数,动态计算每个视图的高度来实现,核心思路如下:

  • 用GeometryReader获取父容器和每个子视图的全局位置,计算子视图中心与父容器中心的距离。
  • 根据距离比例调整视图高度:中间视图(距离为0)使用正常高度,越往两侧距离越大,高度逐渐增大。

示例代码:

struct GradientHeightScrollView: View {
    let items = (1...5).map { "View \($0)" }
    let baseHeight: CGFloat = 200
    let peakHeight: CGFloat = 300
    
    var body: some View {
        GeometryReader { parentGeo in
            HStack(spacing: 16) {
                ForEach(items, id: \.self) { item in
                    GeometryReader { itemGeo in
                        Text(item)
                            .font(.title)
                            .frame(width: 140, height: dynamicHeight(for: itemGeo, parentGeo: parentGeo))
                            .background(Color.green.opacity(0.7))
                            .cornerRadius(12)
                    }
                    .frame(width: 140)
                }
            }
            .frame(maxWidth: .infinity, alignment: .center)
            .padding(.horizontal)
        }
        .frame(height: peakHeight + 20)
    }
    
    private func dynamicHeight(for itemGeo: GeometryProxy, parentGeo: GeometryProxy) -> CGFloat {
        let parentCenter = parentGeo.frame(in: .global).midX
        let itemCenter = itemGeo.frame(in: .global).midX
        let distance = abs(parentCenter - itemCenter)
        
        // 计算高度比例,加入平滑过渡
        let maxPossibleDistance = parentGeo.size.width / 2
        let ratio = min(distance / maxPossibleDistance, 1.0)
        // 用pow函数让过渡更自然,避免线性生硬
        let heightRatio = pow(ratio, 1.5)
        
        return baseHeight + (peakHeight - baseHeight) * heightRatio
    }
}

如果需要添加滚动时的实时高度变化,只需将HStack嵌套进ScrollView(.horizontal),并保持GeometryReader的位置计算逻辑即可。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 13:59:25