Runtime error: precondition failure: attribute failed to set an initial value

Runtime error: precondition failure: attribute failed to set an initial value

我有一个视图 BugSplitView 单独使用时效果很好,但会导致

precondition failure: attribute failed to set an initial value

在预览或模拟器中导航时出错。

视图的上半部分(颜色)和下半部分(颜色)由水平按钮栏分隔,并使用 GeometeryReader 和 split 状态进行布局。当它是 NavigationButton 的目的地时,它不会在预览中正确显示并在模拟器中 运行 时报告上面的断言。删除 BugButtonBar 即可。难倒我了!帮助。

import SwiftUI

struct BugSplitView: View {
    @State var split : CGFloat = 0.75
    var buttons : [BugButtonBar.Info]{
        [BugButtonBar.Info(title: "title", imageName: "text.insert"){}]
    }
    var body: some View {
        GeometryReader{ g in
            VStack(spacing: 0){
                Color.gray
                    .frame(width: g.size.width, height: (g.size.height) * self.split)
                VStack{
                    BugButtonBar(infos: self.buttons)
                    Color(white: 0.3)
                }
                    .frame(height: (g.size.height) * (1 - self.split))
            }
        }.edgesIgnoringSafeArea(.all)
    }
}


struct BugButtonBar : View{

    struct Info : Identifiable {
        var id = UUID()
        var title : String
        var imageName : String
        var action: () -> Void
    }

    var infos : [Info]
    func color() -> Color{
        Color.black
    }
    var body: some View {
        HStack(){
            Spacer()
            ForEach(self.infos){ info in
                Button(action: info.action){
                    Text(info.title)
                }
                Spacer()
            }
        }
    }
}


struct ShowBugView : View{
    var body : some View{
        NavigationView {
            NavigationLink(destination: BugSplitView()){
                Text("Show Bug")
            }
        }
    }
}


struct BugSplitView_Previews: PreviewProvider {
    static var previews: some View {
        Group{
            BugSplitView()
            ShowBugView()
        }
    }
}

问题是您的按钮被声明为已计算的 属性。要解决崩溃,请像这样声明它们:

var buttons = [BugButtonBar.Info(title: "title", imageName: "text.insert"){}]

原来是 struct Info 的 id 属性 出了问题。将其更改为计算的 属性,如下所示:

var id : String {
   title + imageName
}

很好的例子说明了为什么我 love/hate SwiftUI。

对我来说,它是 displayMode 内嵌在导航栏标题中。删除它可以解决此问题。

崩溃

.navigationBarTitle("Title", displayMode: .inline)

没有崩溃

.navigationBarTitle("Title")

由于这个无法直接调试的错误似乎是由许多不同的问题引起的,所以我想我也应该把我的案例放在这里。

就我而言,我得到的错误是:

precondition failure: attribute failed to set an initial value - 128

问题是我试图在其中包含 NavigationView 的 VStack 上呈现 sheet,如下所示:

var body: some View {
    VStack(alignment: .center) {
        if /* some condition */ {
            /* some other content */
        } else {
            NavigationView {
                /* view content */
            }
        }
    }.sheet(isPresented: /* Binding value */) { 
        /* sheet content */
    }
}

解决方法是确保 sheet 显示在 NavigationView 上:

var body: some View {
    NavigationView {
        VStack(alignment: .center) {
            if /* some condition */ {
                /* some other content */
            } else {
                /* view content */
            }
        }
    }.sheet(isPresented: /* Binding value */) { 
        /* sheet content */
    }
}

事后看来很明显,但如果在崩溃最初发生时获得更多信息会更好。

我有这个错误。在我的例子中,这是由于在 if-else 语句的两个块中都有一个 NavigationView 引起的。

// bad
if someBool {
  NavigationView {
    Text("some content")
  }
} else {
  NavigationView {
    Text("different content")
  }
}
// good
NavigationView {
  if someBool {
    Text("some content")
  } else {
    Text("different content")
  }
}

在我的例子中,它是在视图消失时为绑定 属性 设置一个值,属性 会像这样更改视图:

  .onDisappear(perform: {
    withAnimation(.easeInOut) {
        self.action.collageWidthSize = 2.0 /* modifies next view border */
      }
   })

在下一个视图的 onAppear 中设置它修复了它:

   .onAppear {
        withAnimation(.easeInOut) {
            self.action.collageWidthSize = 2.0
        }
    }

好吧,我被这个咬了。 Xcode11.6.

我的观点可能有点令人费解,但我正在做的是,如果用户将视图置于 'edit' 模式,则所有单元格都会更改其表示。当我切换回来时,我似乎随机地收到了这个错误。我通过删除不必要的绑定来修复它(手指仍然交叉)。我将布尔绑定传递给一些子视图,以便它们知道事物处于什么状态,以及如何呈现。问题是,它们不需要响应布尔值的变化,因为无论如何父对象都在重绘,它可以重新创建子对象。他们不需要被通知他们应该改变状态,他们只是被销毁并重新创建。

我使用 NavigationView 作为 TabView 的根:

NavigationView {
   TabView {
   }
}

然后在 TabView 中我也使用了 NavigationView,所以由于这个错误。解决方案是只使用一个 NavigationView.