SwiftUI如何让TextEditor文本全屏显示而非嵌套在滚动框内
问题原因
TextEditor是基于UIKitUIScrollView封装的组件,默认自带独立滚动能力,嵌套在外层ScrollView中时,系统会默认按文本内容的理想高度压缩其尺寸,不会自动拉伸占满可用空间- 外层
ScrollView的内容容器默认按子视图理想尺寸布局,不会主动拉宽子视图匹配屏幕宽度,原代码里的VStack没设置最大宽度,自然也不会撑满横向空间 - 尝试使用的
.fixedSize(horizontal: false, vertical: true)会强制视图按内容理想尺寸渲染,只会让TextEditor高度完全贴合当前文字长度,内容不足时就会出现只占一小块区域的问题,根本撑不满全屏。
问题效果预览:
解决方案
保留外层ScrollView的前提下,做3处调整即可实现全屏效果:
- 给内层
VStack设置maxWidth: .infinity,让内容容器横向撑满整个屏幕宽度 - 关闭
TextEditor自带的滚动能力,避免和外层ScrollView产生滚动冲突,让TextEditor高度可以随内容自适应 - 给
TextEditor设置最小高度为屏幕可用高度,保证内容不足时编辑区域也能占满全屏,内容超出时可以跟随外层ScrollView滚动
修正后代码:
import SwiftUI struct TempView: View { @State private var sampleText = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur." var body: some View { ScrollView { VStack { TextEditor(text: $sampleText) .font(.largeTitle) .scrollDisabled(true) // iOS16+ 可用,关闭TextEditor自身滚动 .frame(minHeight: UIScreen.main.bounds.height - 88) // 88为默认状态栏+导航栏高度,可根据自身UI结构调整 .background(Color.blue) } .frame(maxWidth: .infinity) .background(Color.blue) } .padding(.horizontal, 0) // 清除ScrollView默认横向内边距 } }
如果需要适配iOS16以下版本,可以加一个扩展来关闭TextEditor的滚动:
extension TextEditor { func disableEditorScroll() -> some View { self.onAppear { UITextView.appearance().isScrollEnabled = false } } }
把代码里的.scrollDisabled(true)替换为.disableEditorScroll()即可。
如果不需要在TextEditor上方添加其他需要滚动的内容,完全可以去掉外层多余的ScrollView,直接让TextEditor撑满根视图,代码更简洁:
import SwiftUI struct TempView: View { @State private var sampleText = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur." var body: some View { TextEditor(text: $sampleText) .font(.largeTitle) .frame(maxWidth: .infinity, maxHeight: .infinity) .background(Color.blue) .ignoresSafeArea() // 需要覆盖安全区实现完全全屏时加这行 } }
内容的提问来源于stack exchange,提问作者Hitesh Suthar
相关产品推荐
相关产品推荐

