SwiftUI TextField在ZStack内部的VStack中被禁用(使用TextField模拟警报)

SwiftUI TextField在ZStack内部的VStack中被禁用(使用TextField模拟警报),swiftui,textfield,Swiftui,Textfield,我需要在SwiftUI中发出警报,该警报中有一个可编辑的文本字段。目前,SwiftUI不支持这一点(从Xcode 11.3开始),因此我正在寻找解决方法 我知道我可以通过将普通的UIKit位包装在一个UIHostingController中来实现,但我真的想坚持使用全快速的UI实现 我在一个ZStack中有两个vstack,前面的一个(带有文本视图的)被隐藏并禁用,直到你点击按钮。看看这个: 导入快捷界面 结构ContentView:View{ @状态变量isShowingEditField=f

我需要在SwiftUI中发出警报,该警报中有一个可编辑的文本字段。目前,SwiftUI不支持这一点(从Xcode 11.3开始),因此我正在寻找解决方法

我知道我可以通过将普通的UIKit位包装在一个UIHostingController中来实现,但我真的想坚持使用全快速的UI实现

我在一个ZStack中有两个vstack,前面的一个(带有文本视图的)被隐藏并禁用,直到你点击按钮。看看这个:

导入快捷界面
结构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()//哇,真管用。你知道吗