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

SwiftUI使用DragGesture实现拖动切换视图时黑色背景过渡的方法

实现方案

核心调整思路是不再用if条件控制两个视图的显隐,而是让两个视图常驻视图层级,通过拖动偏移量实时控制两个视图的位置、透明度,同时在层级底层加固定黑色背景层,即可实现拖动过程中的实时过渡效果。

完整实现代码

struct Swipe: View {
    // 滑动容器宽度,可根据实际需求调整
    private let containerWidth: CGFloat = UIScreen.main.bounds.width
    // 标记当前显示的视图:0=矩形 1=圆形
    @State private var currentIndex: Int = 0
    @State private var xOffset: CGFloat = 0.0
    
    var body: some View {
        VStack {
            Text("Current xOffset: \(xOffset)")
            ZStack(alignment: .center) {
                // 黑色过渡背景
                Color.black
                    .frame(width: containerWidth, height: 300)
                
                // 矩形视图
                Rectangle()
                    .foregroundColor(.red)
                    .frame(width: 100, height: 100)
                    // 实时计算偏移:选中时跟随拖动偏移,未选中时向左移出容器
                    .offset(x: xOffset + CGFloat(currentIndex == 0 ? 0 : -containerWidth))
                    // 透明度跟随拖动进度变化
                    .opacity(1 - abs(xOffset) / containerWidth)
                
                // 圆形视图
                Circle()
                    .frame(width: 250, height: 250)
                    .foregroundColor(.blue)
                    // 实时计算偏移:选中时跟随拖动偏移,未选中时向右移出容器
                    .offset(x: xOffset + CGFloat(currentIndex == 1 ? 0 : containerWidth))
                    .opacity(abs(xOffset) / containerWidth)
            }
            .frame(width: containerWidth, height: 300)
            .clipped() // 裁剪容器外的视图,避免未展示的视图漏出
            .gesture(
                DragGesture()
                    .onChanged { value in
                        xOffset = value.translation.width
                    }
                    .onEnded { value in
                        withAnimation(.spring()) {
                            // 拖动距离超过容器1/3则触发视图切换
                            let threshold = containerWidth / 3
                            if value.translation.width < -threshold {
                                currentIndex = min(currentIndex + 1, 1)
                            } else if value.translation.width > threshold {
                                currentIndex = max(currentIndex - 1, 0)
                            }
                            xOffset = 0
                        }
                    }
            )
        }
    }
}

关键改动说明

  • 层级底层新增固定黑色Color视图,满足过渡阶段背景为黑色的需求
  • 移除原控制显隐的布尔变量,改用currentIndex标记当前显示视图,两个视图常驻层级,拖动过程中通过offset实时控制位置,实现跟随拖动的进出效果
  • 透明度参数和拖动偏移量关联,实现两个视图的渐入渐出过渡
  • 新增clipped()修饰符裁剪容器外内容,避免未显示的视图出现在屏幕其他区域
  • 调整结束拖动的判断逻辑,用容器宽度比例作为切换阈值,适配不同屏幕尺寸

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 12:06:02