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

如何配置ScrollView内的DisclosureGroup,收缩时为其他视图腾空间?

SwiftUI 布局问题:DisclosureGroup收缩时TopView文本无法恢复完整字号

问题描述

TopView展示带最小缩放因子的大字号文本,BottomView在ScrollView内通过DisclosureGroup展示另一组文本。当前不管DisclosureGroup是否展开,TopView的文本都处于压缩状态。期望效果是:

  • DisclosureGroup展开时:TopView文本自动压缩适配空间
  • DisclosureGroup收缩时:BottomView占用空间缩小,TopView文本恢复完整字号,布局自动为TopView腾出足够空间

复现代码

import SwiftUI

@main
struct MainApp: App {
  
  var body: some Scene {
    WindowGroup {
      VStack(spacing: 8) {
        TopView()
        BottomView()
      }
    }
  }
}

struct TopView: View {
  var body: some View {
    GeometryReader { geometry in
      VStack(spacing: 8) {
        ForEach(0 ..< 15) { int in
          Text("\(int)")
            .foregroundColor(.black)
            .font(.system(size: 75))
            .minimumScaleFactor(0.50)
            .background(int % 2 == 0 ? .green : .red)
            .frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity, alignment: .center)
        }
        .padding(0)
      }
    }
//    .layoutPriority(1)
  }
}

struct BottomView: View {
  @State var isExpanded = true
  
  var body: some View {
    GeometryReader { geometry in
      ScrollView {
        DisclosureGroup("Sample disclosure", isExpanded: $isExpanded) {
          ForEach(21 ..< 40) { int in
            Text("\(int)")
              .foregroundColor(.black)
              .font(.system(size: 75))
              .minimumScaleFactor(0.5)
          }
        }
        .font(.title)
        .padding()
      }
    }
  }
}

当前现象

  • 展开状态:TopView文本被压缩
    展开时TopView压缩
  • 收缩状态:TopView文本仍保持压缩,未恢复完整字号
    收缩时TopView仍压缩

解决方法

调整布局优先级和BottomView的高度约束逻辑,代码修改如下:

import SwiftUI

@main
struct MainApp: App {
  
  var body: some Scene {
    WindowGroup {
      VStack(spacing: 8) {
        TopView()
        BottomView()
      }
    }
  }
}

struct TopView: View {
  var body: some View {
    VStack(spacing: 8) {
      ForEach(0 ..< 15) { int in
        Text("\(int)")
          .foregroundColor(.black)
          .font(.system(size: 75))
          .minimumScaleFactor(0.50)
          .background(int % 2 == 0 ? .green : .red)
          .frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity, alignment: .center)
      }
      .padding(0)
    }
    .layoutPriority(1) // 启用布局优先级,让TopView优先获取空间
  }
}

struct BottomView: View {
  @State var isExpanded = true
  
  var body: some View {
    ScrollView {
      DisclosureGroup("Sample disclosure", isExpanded: $isExpanded) {
        ForEach(21 ..< 40) { int in
          Text("\(int)")
            .foregroundColor(.black)
            .font(.system(size: 75))
            .minimumScaleFactor(0.5)
        }
      }
      .font(.title)
      .padding()
    }
    .frame(minHeight: 0, maxHeight: .infinity) // 允许BottomView根据内容收缩/扩展高度
  }
}

调整逻辑说明

  1. 启用TopView的布局优先级:layoutPriority(1)让TopView在布局计算时拥有更高权重,空间足够时优先展示完整字号文本,空间不足时才触发文本压缩。
  2. 移除BottomView的GeometryReader:ScrollView本身会自适应内容高度,无需强制占满剩余空间,DisclosureGroup收缩时BottomView会自动缩小高度,把空间让给TopView。
  3. 给BottomView添加弹性高度约束:.frame(minHeight: 0, maxHeight: .infinity)确保BottomView在展开时可以占用剩余空间并支持滚动,收缩时能自动收缩高度。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 04:31:23