我正在构建一个简单的登录屏幕,我注意到当我在 TextField 和 SecureField 之间切换时,我的屏幕移动了一点,我认为这是因为它们的高度发生了变化?或者也许我做错了什么?
这是代码:
struct LoginView: View {
@State var username: String
@State var password: String
@State var showingPassword: Bool = false
var body: some View {
VStack(spacing: 15) {
Text("Welcome")
.font(.largeTitle)
.bold()
.padding(.bottom)
TextField("Username", text: $username)
.customTextField()
.overlay(RoundedRectangle(cornerRadius: 10).stroke(Color("charcoal"), lineWidth: 0.6))
HStack {
if showingPassword {
TextField("Password", text: $password)
.customTextField()
.overlay(RoundedRectangle(cornerRadius: 10).stroke(Color("charcoal"), lineWidth: 0.6))
.border(.pink)
Image(systemName: "eye.slash")
.onTapGesture {
showingPassword.toggle()
}
.border(.pink)
} else {
SecureField("Password", text: $password)
.customTextField()
.overlay(RoundedRectangle(cornerRadius: 10).stroke(Color("charcoal"), lineWidth: 0.6))
.border(.green)
Image(systemName: "eye")
.onTapGesture {
showingPassword.toggle()
}
.foregroundColor(Color("charcoal"))
.border(.green)
}
}
}
.padding(.horizontal)
}
}
和修饰符:
struct TextFieldModifier: ViewModifier {
func body(content: Content) -> some View {
content
.padding(.horizontal)
.padding(.vertical, 12)
.overlay(RoundedRectangle(cornerRadius: 10).stroke(Color.gray, lineWidth: 0.6))
.lineLimit(5)
}
}
extension View {
func customTextField() -> some View {
modifier(TextFieldModifier())
}
}
是的,确实有身高差。您可以通过在视图上使用 Xcode 的 UI 检查器来检查它,就像这样简单:
var body: some View {
VStack {
TextField("Username", text: $username)
SecureField("Password", text: $password)
}
}
在我的模拟器上,文本字段的高度为 22,安全字段的高度为 21。
SecureField
。图片是:
您可以尝试在 Preview.app 或类似应用程序中打开图像并计算像素(我就是这么做的!)。
我不确定这种差异是否是有意为之。
这确实很简陋!我遇到了同样的问题,并通过在两个字段中添加
.frame(height: 22)
来解决它,在 TextField
上可能不需要它,但我决定将其添加到那里,以防在某些情况下它的渲染方式有所不同。
这是我的完整代码片段:
HStack {
Group {
if showPassword {
TextField("Password",
text: $password,
prompt: Text("Password"))
.frame(height: 22)
} else {
SecureField("Password",
text: $password,
prompt: Text("Password"))
.frame(height: 22)
}
}
.padding(10)
Button {
showPassword.toggle()
} label: {
Image(systemName: showPassword ? "eye.slash" : "eye")
.padding(.horizontal)
}
}