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

SwiftUI实现卡片全屏展开并禁用ScrollView滚动的技术需求

解决方案:实现SwiftUI可展开全屏卡片并控制ScrollView滚动

要实现你需要的效果,核心是把卡片的展开状态提升到父视图统一管理,这样才能控制其他卡片的显示、ScrollView的滚动状态,同时通过GeometryReader获取屏幕尺寸来实现全屏卡片。以下是修改后的完整代码:

修改后的DisciplineView

import SwiftUI

struct DisciplineView: View {
    // 跟踪当前展开的卡片标题,nil表示无卡片展开
    @State private var expandedCard: String?
    
    var body: some View {
        GeometryReader { geometry in
            ScrollView(showsIndicators: false) {
                LazyVStack {
                    // 根据展开状态决定显示内容
                    if let expandedTitle = expandedCard {
                        // 只显示展开的卡片,并设置高度为屏幕高度
                        Card(cardTitle: expandedTitle, isExpanded: true) {
                            withAnimation {
                                expandedCard = nil
                            }
                        }
                        .frame(height: geometry.size.height)
                    } else {
                        // 无卡片展开时显示全部卡片
                        Card(cardTitle: "Notes", isExpanded: false) {
                            withAnimation {
                                expandedCard = "Notes"
                            }
                        }
                        Card(cardTitle: "Planner", isExpanded: false) {
                            withAnimation {
                                expandedCard = "Planner"
                            }
                        }
                        Card(cardTitle: "Homeworks / Exams", isExpanded: false) {
                            withAnimation {
                                expandedCard = "Homeworks / Exams"
                            }
                        }
                    }
                }
                .ignoresSafeArea()
            }
            // 有卡片展开时禁用ScrollView滚动
            .disabled(expandedCard != nil)
        }
    }
}

struct DisciplineView_Previews: PreviewProvider {
    static var previews: some View {
        DisciplineView()
    }
}

修改后的Card组件

import SwiftUI

struct Card: View {
    let cardTitle: String
    let isExpanded: Bool
    let onTap: () -> Void
    
    var body: some View {
        RoundedRectangle(cornerRadius: 30, style: .continuous)
            .stroke(style: StrokeStyle(lineWidth: 5, lineCap: .round, lineJoin: .round))
            .foregroundColor(.gray.opacity(0.2))
            .frame(width: .infinity, height: isExpanded ? nil : 50)
            .background(
                VStack {
                    cardInfo
                    if isExpanded { Spacer() }
                }
                .padding(isExpanded ? 10 : 0)
            )
            // 展开时添加深色背景,配合白色文字提升可读性
            .background(isExpanded ? Color.black : Color.white)
    }
    
    var cardInfo: some View {
        HStack {
            Text(cardTitle)
                .font(.title).bold()
                .foregroundColor(isExpanded ? .white : .black)
                .padding(.leading, 10)
            
            Spacer()
            
            Image(systemName: isExpanded ? "arrowtriangle.up.square.fill" : "arrowtriangle.down.square.fill")
                .padding(.trailing, 10)
                .onTapGesture(perform: onTap)
        }
    }
}

struct Card_Previews: PreviewProvider {
    static var previews: some View {
        Card(cardTitle: "Test", isExpanded: false, onTap: {})
    }
}

关键修改说明

  • 状态统一管理:将卡片的展开状态从Card内部移到父视图DisciplineView,通过expandedCard变量跟踪当前展开的卡片,实现隐藏其他卡片的逻辑。
  • 全屏卡片实现:利用GeometryReader获取屏幕高度,给展开的卡片设置对应高度,确保占满整个屏幕。
  • 禁用ScrollView滚动:通过.disabled(expandedCard != nil),在有卡片展开时直接禁用ScrollView的交互,停止滚动。
  • 组件解耦:Card组件只负责展示逻辑,点击和状态由父视图控制,符合SwiftUI单向数据流的设计思路。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 13:10:45