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

SwiftUI中如何自定义具备默认功能的DisclosureGroup(下拉组件)?

自定义SwiftUI DisclosureGroup组件,实现完全自定义需求

原生SwiftUI的DisclosureGroup存在功能局限:无法移除左侧默认的蓝色箭头指示器,且标题区域的样式自定义空间有限(比如不能自由修改文字颜色、用图片替代文本)。下面实现一个完全自定义的CustomDisclosureGroup,既保留原生组件的展开/收起核心功能,又支持完全自定义的标题区域和内容区域,还能添加额外的点击回调逻辑。

自定义组件实现代码

import SwiftUI

struct CustomDisclosureGroup<Prompt: View, Content: View>: View {
    @Binding var isExpanded: Bool
    let actionOnClick: () -> Void
    let prompt: Prompt
    let expandedView: Content
    
    var body: some View {
        VStack(alignment: .leading, spacing: 0) {
            Button(action: actionOnClick) {
                prompt
                    .frame(maxWidth: .infinity, alignment: .leading)
            }
            
            if isExpanded {
                expandedView
                    .transition(.opacity.combined(with: .slide))
            }
        }
    }
}

// 可选:添加简化初始化器,支持直接传入标题文本
extension CustomDisclosureGroup where Prompt == Text {
    init(isExpanded: Binding<Bool>, actionOnClick: @escaping () -> Void, title: String, expandedView: Content) {
        self.isExpanded = isExpanded
        self.actionOnClick = actionOnClick
        self.prompt = Text(title)
        self.expandedView = expandedView
    }
}

使用示例

按照你期望的方式使用自定义组件,完全自由定制标题区域和展开内容:

struct ContentView: View {
    @State private var isExpanded = false
    
    var body: some View {
        CustomDisclosureGroup(isExpanded: $isExpanded, actionOnClick: {
            isExpanded.toggle()
            print("执行额外逻辑")
        }, prompt: {
            HStack {
                Text("自定义标题行")
                    .foregroundColor(.white)
                Spacer()
                Image("customArrow")
                    .resizable()
                    .frame(width: 12, height: 12)
                    // 可选:根据展开状态旋转箭头
                    .rotationEffect(.degrees(isExpanded ? 90 : 0))
            }
            .background(Color.blue)
            .padding()
        }, expandedView: {
            VStack {
                Text("自定义展开内容")
                Text("第二行内容")
            }
            .background(Color.red)
            .padding()
        })
        .padding()
    }
}

组件特性说明

  • 完全自定义标题区域(prompt参数):支持任意View组合,可修改文字颜色、添加图片、自定义背景等
  • 完全自定义展开内容区域(expandedView参数):自由放置任意视图
  • 支持点击回调(actionOnClick参数):除了展开/收起,可执行额外业务逻辑
  • 保留核心的展开/收起状态绑定(isExpanded Binding):方便外部控制状态

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 13:36:29