SwiftUI中TextField背景图设Aspect fit时iPad端宽度受限如何解决

iPhone端界面显示正常,但在iPad设备上,
TextField的宽度无法自适应增大。如果我将内容模式修改为fill,两个输入框会出现重叠,请问该如何修复这个问题?
原代码如下:
var body: some View { VStack (alignment: .center,spacing :35){ TextField("Enter Username", text: $username) .frame(minWidth: 0 , maxWidth: .infinity) .frame(height: 55) .background(Image("userinput").resizable().aspectRatio(contentMode: .fit)) .multilineTextAlignment(.center) .padding([.leading,.trailing],15) TextField("Enter Password", text: $username) .frame(minWidth: 0 , maxWidth: .infinity) .frame(height: 55) .background(Image("pswrd").resizable().aspectRatio(contentMode: .fit)) .multilineTextAlignment(.center) .padding([.leading,.trailing],15) Button("SIGN IN") { action = true print("Just tapped") } .frame(minWidth: 0 , maxWidth: .infinity) .frame(height: 55) .background(Color(red: 46/255, green: 152/255, blue: 182/255)) .foregroundColor(.white) .cornerRadius(5) .padding([.leading,.trailing],50) } }
问题根源
TextField 背景的 Image 加了 aspectRatio(contentMode: .fit) 修饰符:iPad 宽度更大时,背景图为了保持原始宽高比、完整显示在你指定的55pt固定高度内,宽度只能维持和iPhone端接近的大小,看起来就像输入框没有自适应拉宽;如果换成fill模式,背景图为了填满输入框的宽度,高度会超出55pt的限制,没有裁剪就会和上下控件重叠。
修复方案(两种可选)
方案1:接受背景图轻微拉伸,直接适配输入框大小(适配成本最低)
直接去掉背景图片的 aspectRatio(contentMode: .fit) 修饰符即可,resizable() 默认会拉伸图片填满父容器,刚好匹配你给 TextField 设置的固定高度和最大宽度,不会出现溢出或宽度不足的问题。
方案2:保留背景图原始比例,裁剪超出部分
把背景图片的修饰符替换为 aspectRatio(contentMode: .fill) 后追加 .clipped(),背景图会按比例填满整个输入框的frame,超出55高度的部分会被裁掉,不会出现重叠问题。
另外你现有代码里有个笔误:密码输入框绑定的变量还是 $username,记得改成你对应的密码变量 $password,避免输入同步异常。
修改后代码示例
var body: some View { VStack (alignment: .center,spacing :35){ TextField("Enter Username", text: $username) .frame(minWidth: 0 , maxWidth: .infinity) .frame(height: 55) // 这里用方案1:去掉aspectRatio,直接拉伸适配 .background(Image("userinput").resizable()) .multilineTextAlignment(.center) .padding([.leading,.trailing],15) TextField("Enter Password", text: $password) // 修正绑定变量 .frame(minWidth: 0 , maxWidth: .infinity) .frame(height: 55) // 如果选方案2就用下面这个写法 // .background(Image("pswrd").resizable().aspectRatio(contentMode: .fill).clipped()) .background(Image("pswrd").resizable()) .multilineTextAlignment(.center) .padding([.leading,.trailing],15) Button("SIGN IN") { action = true print("Just tapped") } .frame(minWidth: 0 , maxWidth: .infinity) .frame(height: 55) .background(Color(red: 46/255, green: 152/255, blue: 182/255)) .foregroundColor(.white) .cornerRadius(5) .padding([.leading,.trailing],50) } }
内容的提问来源于stack exchange,提问作者venkat
相关产品推荐
相关产品推荐

