如何将文本固定在UITextView顶部 解决输入时placeholder下移问题
问题根因
偏移问题来自两个叠加影响因素:
- 输入框的
padding(.top)会根据isHideHolder动态变化,直接改变了输入框自身的frame基准位置,作为背景的placeholder的对齐锚点也会跟着移动 - 输入框高度动态伸缩时,背景视图的对齐基准也会随宿主frame同步变化,固定的offset值无法适配动态变化的锚点
方案1:最小改动适配现有逻辑
只要把placeholder从输入框的background修饰符中移到外层,和输入框放在同一个ZStack里管理,同时删掉输入框的动态top padding即可:
VStack (alignment: .leading) { VStack { ZStack(alignment: .leading) { // placeholder 位置和输入框高度解耦,不受输入框frame变化影响 Text("placeholder") .scaleEffect(isHideHolder ? 0.8: 1) .offset(x: isHideHolder ? -14 : 0, y: isHideHolder ? -22 : 0) .foregroundColor(.gray) DynamicTextField(object: dynamicSize, text: $text, state: $state, placeholder: placeholder) .frame(height: self.dynamicSize.size < 100 ? self.dynamicSize.size : 100) } } .padding() .background(Color.white) .cornerRadius(12) }
如果需要保留原来的输入文字顶部间距,直接给DynamicTextField加固定的top padding即可,不要用动态值。
方案2:更稳定的无硬编码实现
如果要避免硬编码offset数值适配不同字体、设备尺寸,可以用alignmentGuide替代offset实现浮动效果,位置计算会自适应文本自身尺寸:
VStack (alignment: .leading) { VStack { ZStack(alignment: .leading) { Text("placeholder") .foregroundColor(.gray) .scaleEffect(isHideHolder ? 0.8 : 1) // 位置基于自身高度计算,不需要写死offset .alignmentGuide(.top, computeValue: { dimension in isHideHolder ? -dimension.height - 4 : dimension.height/2 }) .alignmentGuide(.leading, computeValue: { dimension in isHideHolder ? -dimension.width * 0.1 : 0 }) DynamicTextField(object: dynamicSize, text: $text, state: $state, placeholder: placeholder) .frame(height: self.dynamicSize.size < 100 ? self.dynamicSize.size : 100) .padding(.top, 8) } } .padding() .padding(.top, 12) // 顶部预留浮动placeholder的展示空间 .background(Color.white) .cornerRadius(12) }
如果需要输入内容后隐藏placeholder,直接给Text加.opacity(isHideHolder ? 1 : 0)即可。
内容的提问来源于stack exchange,提问作者PixieKP
相关产品推荐
相关产品推荐

