SwiftUI笔记视图:TextEditor内部滚动边距设置(避免文本裁剪)
针对你遇到的问题,核心是要给TextEditor的滚动内容添加底部额外空间,而非给视图本身加padding,这样就能让文本滚动到Footer下方且完整显示,无需手动添加换行符。
iOS 16+ 简洁方案
利用SwiftUI 3.0新增的scrollContentInsets修饰符,直接给滚动内容设置底部插入值,数值可根据Footer高度或你想要的5个换行高度调整:
var body: some View { ZStack(alignment: .bottom) { VStack(alignment: .leading) { Text("\(note.date.formatted())") .padding([.leading, .trailing]) TextEditor(text: $note.text) .padding() // 设置滚动内容的底部插入,可替换为字体行高×5的计算值 .scrollContentInsets(.init(top: 0, leading: 0, bottom: 150, trailing: 0)) } Footer {} } }
如果要精确匹配5个换行的高度,可先计算字体行高:
// 在视图内定义计算属性 private var bottomInset: CGFloat { let lineHeight = UIFont.preferredFont(forTextStyle: .body).lineHeight return lineHeight * 5 } // 替换到scrollContentInsets中使用 .scrollContentInsets(.init(top: 0, leading: 0, bottom: bottomInset, trailing: 0))
iOS 15及以下兼容方案
针对更低版本iOS,需要通过UIViewRepresentable包装原生UITextView,设置其contentInset属性:
struct CustomTextEditor: UIViewRepresentable { @Binding var text: String let bottomInset: CGFloat func makeUIView(context: Context) -> UITextView { let textView = UITextView() // 匹配SwiftUI默认字体样式 textView.font = UIFont.preferredFont(forTextStyle: .body) // 设置内容底部插入 textView.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: bottomInset, right: 0) return textView } func updateUIView(_ uiView: UITextView, context: Context) { uiView.text = text uiView.delegate = context.coordinator } func makeCoordinator() -> Coordinator { Coordinator(self) } class Coordinator: NSObject, UITextViewDelegate { var parent: CustomTextEditor init(_ parent: CustomTextEditor) { self.parent = parent } func textViewDidChange(_ textView: UITextView) { parent.text = textView.text } } } // 替换原TextEditor使用 var body: some View { ZStack(alignment: .bottom) { VStack(alignment: .leading) { Text("\(note.date.formatted())") .padding([.leading, .trailing]) CustomTextEditor(text: $note.text, bottomInset: UIFont.preferredFont(forTextStyle: .body).lineHeight * 5) .padding() } Footer {} } }
为什么直接加padding不行?
.padding([.bottom], 150)是给TextEditor视图本身添加内边距,这会挤压文本的可编辑区域,导致文本显示空间变小出现裁剪;而scrollContentInsets或contentInset是给滚动内容添加额外的底部空白区域,文本可以滚动到该区域内,不会被裁剪,同时Footer悬浮在视图上层,文本能完整滚动到Footer下方。
内容的提问来源于stack exchange,提问作者kabukiman
相关产品推荐
相关产品推荐

