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

如何让Form中的SwiftUI TextEditor动态占满剩余屏幕空间?

解决方案:让Form中的TextEditor动态占满剩余屏幕空间

要实现TextEditor在Form中动态适配所有设备的剩余空间,无需硬编码高度,可以利用SwiftUI的自适应布局优先级,通过设置frame(maxHeight: .infinity)让视图自动填充可用空间。以下是具体实现方案:

核心代码修改

import SwiftUI
import PlaygroundSupport

struct ContentView: View {
    @State var text = String()
    
    var body: some View {
        Form {
            Section("Section") {
                Toggle("Toggle", isOn: .constant(true))
                // 调整LabeledContent和内部TextEditor的布局优先级
                LabeledContent("TextEditor") {
                    TextEditor(text: $text)
                        .frame(maxHeight: .infinity) // 让TextEditor填充LabeledContent的可用高度
                }
                .frame(maxHeight: .infinity) // 让LabeledContent占满Section的剩余空间
            }
        }
        .frame(maxHeight: .infinity) // 确保Form占满整个屏幕高度
    }
}

PlaygroundPage.current.setLiveView(ContentView())

原理说明

  1. Form占满屏幕:给Form添加.frame(maxHeight: .infinity),确保它能利用设备屏幕的全部可用高度(自动适配安全区域)。
  2. LabeledContent扩展高度:默认LabeledContent的高度由内部内容决定,设置.frame(maxHeight: .infinity)后,它会自动扩展以占据Section中除Toggle外的剩余空间。
  3. TextEditor填充空间:给TextEditor添加.frame(maxHeight: .infinity),让它完全填充LabeledContent的可用高度,实现动态适配。

进阶精确控制(可选)

如果需要更精确地排除其他元素的高度(比如Section标题、Toggle的高度),可以使用PreferenceKey来获取这些元素的实际高度,再计算TextEditor的可用高度:

步骤1:定义高度偏好键

struct ElementHeightKey: PreferenceKey {
    static var defaultValue: CGFloat = 0
    static func reduce(value: inout CGFloat, nextValue: () -> CGFloat) {
        value += nextValue()
    }
}

步骤2:获取元素高度并计算剩余空间

struct ContentView: View {
    @State var text = String()
    @State private var fixedElementsHeight: CGFloat = 0
    
    var body: some View {
        GeometryReader { screenGeo in
            Form {
                Section("Section") {
                    Toggle("Toggle", isOn: .constant(true))
                        .background(
                            GeometryReader { toggleGeo in
                                Color.clear
                                    .preference(key: ElementHeightKey.self, value: toggleGeo.size.height)
                            }
                        )
                    
                    LabeledContent("TextEditor") {
                        TextEditor(text: $text)
                            .frame(height: screenGeo.size.height 
                                    - fixedElementsHeight 
                                    - screenGeo.safeAreaInsets.top 
                                    - screenGeo.safeAreaInsets.bottom 
                                    - 40) // 额外减去Section的内边距和标题高度
                    }
                }
            }
            .frame(maxWidth: .infinity, maxHeight: .infinity)
            .onPreferenceChange(ElementHeightKey.self) { height in
                fixedElementsHeight = height
            }
        }
    }
}

这个方案会更精准地适配不同设备上元素的实际高度,避免因系统样式变化导致的布局偏差。

内容的提问来源于stack exchange,提问作者Tobias Müller

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 00:31:01