SwiftUI TextField在ZStack内部的VStack中被禁用(使用TextField模拟警报)
我需要在SwiftUI中发出警报,该警报中有一个可编辑的文本字段。目前,SwiftUI不支持这一点(从Xcode 11.3开始),因此我正在寻找解决方法 我知道我可以通过将普通的UIKit位包装在一个UIHostingController中来实现,但我真的想坚持使用全快速的UI实现 我在一个ZStack中有两个vstack,前面的一个(带有文本视图的)被隐藏并禁用,直到你点击按钮。看看这个:SwiftUI TextField在ZStack内部的VStack中被禁用(使用TextField模拟警报),swiftui,textfield,Swiftui,Textfield,我需要在SwiftUI中发出警报,该警报中有一个可编辑的文本字段。目前,SwiftUI不支持这一点(从Xcode 11.3开始),因此我正在寻找解决方法 我知道我可以通过将普通的UIKit位包装在一个UIHostingController中来实现,但我真的想坚持使用全快速的UI实现 我在一个ZStack中有两个vstack,前面的一个(带有文本视图的)被隐藏并禁用,直到你点击按钮。看看这个: 导入快捷界面 结构ContentView:View{ @状态变量isShowingEditField=f
导入快捷界面
结构ContentView:View{
@状态变量isShowingEditField=false
@状态变量文本:String=“12345”
var body:一些观点{
ZStack{
VStack{
文本(“值为\(self.Text)”)
按钮(操作:{
打印(“按钮”)
self.isShowingEditField=true
}) {
文本(“点击测试”)
}
}
.disabled(self.isShowingEditField)
.不透明度(self.isShowingEditField?0.25:1.00)
VStack(对齐:。中心){
文本(“编辑文本”)
文本字段(“,文本:self.$text)
.multilitextalignment(.center)
.lineLimit(1)
分隔器()
HStack{
按钮(操作:{
动画片{
self.isShowingEditField=false
打印(“已完成…值为\(self.text)”)
}
}) {
文本(“确定”)
}
}
}
.padding()
.背景(颜色.白色)
.阴影(半径:CGFloat(1.0))
.disabled(!self.isShowingEditField)
.不透明度(self.isShowingEditField?1.0:0.0)
}
}
}
这对我来说似乎很有用。在两个VStacks之间切换效果很好,但是TextField不可编辑
它看起来像是被禁用了,但事实并非如此。显式.disabled(false)到文本字段没有帮助。此外,它应该已经启用,因为1)这是默认设置,2)它所在的VStack被专门设置为已启用,3)OK按钮正常工作
想法/解决方法?谢谢 这真的很可笑,但如果只注释一行代码,问题就消失了:
/.shadow(半径:CGFloat(1.0))
我对它进行了评论,一切正常。我认为您需要在自定义警报视图中的某个位置使用ZStack
,以避免出现这种情况。。嗯,也许是巴格
更新
尝试一些实验。如果在该视图中仅保留此代码:
struct CustomAlertWithTextField:View{
@状态变量isShowingEditField=false
@状态变量文本:String=“12345”
var body:一些观点{
TextField(“,text:$text)
.padding()
.阴影(半径:CGFloat(1.0))
}
}
它不会再起作用了。仅当您注释.padding()
或.shadow(…)
但是如果你重新启动Xcode-这段代码开始工作了(这让我发疯了)。在Xcode版本11.2(11B52)上试用过
更新2工作代码版本:
struct CustomAlertWithTextField:View{
@状态变量isShowingEditField=false
@状态变量文本:String=“12345”
var body:一些观点{
ZStack{
VStack{
文本(“值为\(self.Text)”)
按钮(操作:{
打印(“按钮”)
self.isShowingEditField=true
}) {
文本(“点击测试”)
}
}
.disabled(self.isShowingEditField)
.不透明度(self.isShowingEditField?0.25:1.00)
ZStack{
矩形()
.填充(颜色.白色)
.框架(宽度:300,高度:100)
.shadow(半径:1)//在此处移动了阴影,因此它现在不会影响TextField
VStack(对齐:。中心){
文本(“编辑文本”)
文本字段(“,文本:self.$text)
.multilitextalignment(.center)
.lineLimit(1)
.框架(宽度:298)
分隔器().框架(宽度:300)
HStack{
按钮(操作:{
动画片{
self.isShowingEditField=false
打印(“已完成…值为\(self.text)”)
}
}) {
文本(“确定”)
}
}
}
}
.padding()
.背景(颜色.白色)
.disabled(!self.isShowingEditField)
.不透明度(self.isShowingEditField?1.0:0.0)
}
}
}
您需要使用一些方法强制更新文本字段。例如:
TextField("", text: self.$text)
.multilineTextAlignment(.center)
.lineLimit(1)
.id(self.isShowingEditField)
经过一些研究,我通过向VStack添加
.clipped()
解决了这个问题
对于您的问题,它将如下所示:
VStack(alignment: .center) {
Text("Edit the text")
TextField("", text: self.$text)
.multilineTextAlignment(.center)
.lineLimit(1)
Divider()
HStack {
Button(action: {
withAnimation {
self.isShowingEditField = false
print("completed... value is \(self.text)")
}
}) {
Text("OK")
}
}
}
.padding()
.clipped() // <- here
.background(Color.white)
.shadow(radius: CGFloat(1.0))
.disabled(!self.isShowingEditField)
.opacity(self.isShowingEditField ? 1.0 : 0.0)
VStack(对齐:。中心){
文本(“编辑文本”)
文本字段(“,文本:self.$text)
.multilitextalignment(.center)
.lineLimit(1)
分隔器()
HStack{
按钮(操作:{
动画片{
self.isShowingEditField=false
打印(“已完成…值为\(self.text)”)
}
}) {
文本(“确定”)
}
}
}
.padding()
.clipped()//哇,真管用。你知道吗