键盘关闭时的 SwiftUI 按钮故障
Posted
技术标签:
【中文标题】键盘关闭时的 SwiftUI 按钮故障【英文标题】:SwiftUI button glitches on keyboard dismiss 【发布时间】:2021-12-30 22:42:56 【问题描述】:我的视图上有一个按钮,当按下该按钮时,它会调用hideKeyboard
函数,该函数如下:
func hideKeyboard()
let resign = #selector(UIResponder.resignFirstResponder)
UIApplication.shared.sendAction(resign, to: nil, from: nil, for: nil)
但是,当按下按钮并关闭键盘时,会在视图向下移动时按钮保持原位的位置出现故障: https://giphy.com/gifs/Z7qCDpRSGoOb9CbVRQ
可重现的例子:
import SwiftUI
struct TestView: View
@State private var username: String = ""
@State private var password: String = ""
@State private var isAnimating: Bool = false
var lightGrey = Color(red: 239.0/255.0,
green: 243.0/255.0,
blue: 244.0/255.0)
var body: some View
ZStack()
VStack()
Spacer()
Text("Text")
.font(.title)
.fontWeight(.semibold)
.padding(.bottom, 15)
.frame(maxWidth: .infinity, alignment: .leading)
Text("Text")
.font(.subheadline)
.padding(.bottom)
.frame(maxWidth: .infinity, alignment: .leading)
TextField("username", text: $username)
.padding()
.background(self.lightGrey)
.cornerRadius(5.0)
.padding(.bottom, 20)
SecureField("password", text: $password)
.padding()
.background(self.lightGrey)
.cornerRadius(5.0)
.padding(.bottom, 20)
Button(action:
self.hideKeyboard()
login()
)
if isAnimating
ProgressView()
.colorScheme(.dark)
.font(.headline)
.foregroundColor(.white)
.padding()
.frame(maxWidth: .infinity)
.background(Color.green)
.cornerRadius(10.0)
.padding(.bottom, 20)
else
Text("Text")
.font(.headline)
.foregroundColor(.white)
.padding()
.frame(maxWidth: .infinity)
.background(Color.green)
.cornerRadius(10.0)
.padding(.bottom, 20)
.disabled(username.isEmpty || password.isEmpty || isAnimating)
Text("Text")
.font(.footnote)
.frame(maxWidth: .infinity, alignment:.leading)
Spacer()
.padding()
.padding(.bottom, 150)
.background(Color.white)
func hideKeyboard()
let resign = #selector(UIResponder.resignFirstResponder)
UIApplication.shared.sendAction(resign, to: nil, from: nil, for: nil)
func login()
isAnimating = true
struct TestView_Previews: PreviewProvider
static var previews: some View
TestView()
【问题讨论】:
你能加入minimal reproducible example吗?没有它,调试起来将非常具有挑战性。 我很抱歉。我根据您的建议编辑了问题。 【参考方案1】:这是由于按钮内的视图替换,在下面找到一个固定的重新布局。
使用 Xcode 13.2 / ios 15.2 测试(为演示激活了慢动画)
Button(action:
self.hideKeyboard()
login()
)
VStack // << persistent container !!
if isAnimating
ProgressView()
.colorScheme(.dark)
else
Text("Text")
.foregroundColor(.white)
.font(.headline)
.padding()
.frame(maxWidth: .infinity)
.background(Color.green)
.cornerRadius(10.0)
.padding(.bottom, 20)
.disabled(username.isEmpty || password.isEmpty || isAnimating)
【讨论】:
【参考方案2】:UIApplication.shared.sendAction
和 SwiftUI 之间似乎存在冲突:隐藏键盘会启动动画,但更新 isAnimating
属性会重置它。
改变调用顺序解决问题:
Button(action:
login()
self.hideKeyboard()
)
【讨论】:
以上是关于键盘关闭时的 SwiftUI 按钮故障的主要内容,如果未能解决你的问题,请参考以下文章