2

I have a view MachineDetailsView.

Here are code.

internal struct MachineDetailsView {
  @State internal var mediaPageIndex = 0
  @State internal var showPriceView = false
  internal var mediaViews: [MediaView] {
        var views = [MediaView]()
        
        guard let medias = machine?.media else { return views }
        
        medias.forEach {
            views.append(MediaView(media: $0))
        }
        
        return views
    }

    internal var body: some View {
        ZStack(alignment: .topLeading) {
            VStack {
                PagerView(
                    index: $mediaPageIndex,
                    leftInset: 0.15,
                    rightInset: 0.15,
                    pages: mediaViews
                )
                    .frame(height: 238)
                
                PagerDotsView(
                    index: $mediaPageIndex,
                    pages: mediaViews
                )
            }
            .frame(minWidth: 0, maxWidth: .infinity)
            .background(Color(.brand))
            .padding(.vertical, Spacing.extraTiny)
            
            Button(action: {
                self.showPriceView = true
            }) {
                Text("Price")
                    .modifier(ButtonStyle.Filled())
                    .padding(.horizontal)
            }
        }
        .navigationLink(destination: LazyView { MachinePriceView(viewModel: self.viewModel) },
                        isActive: $showPriceView)
    }

As you can see, when hit "Price" button, app showing MachinePriceView (working fine) But when hit back navigation bar button on MachinePriceView, app crashing with below logs.

AttributeGraph precondition failure: attribute failed to set an initial value: 2036248,
ForEachChild<Array<MediaView>, UUID,    ModifiedContent<ModifiedContent<ModifiedContent<ModifiedContent<MediaView, _FrameLayout>, _TransactionModifier>, _OpacityEffect>, _TransactionModifier>>.

I am not sure why app crashing. Here are code for MediaView

internal struct MediaView: View, Identifiable, Equatable {
    internal let id = UUID()
    internal let media: Media
    
    internal var body: some View {
        VStack {
            if media.mediaType == .image {
                KFImage(URL(string: media.mediaUrl ?? ""))
                    .resizable()
                    .aspectRatio(contentMode: .fit)
                    .clipped()
            } else {
                if media.mediaUrl != nil {
                    YoutubePlayer(videoURL: media.mediaUrl!)
                        .frame(width: UIScreen.main.bounds.width * 0.8, height: 208)
                }
            }
        }
        .frame(width: UIScreen.main.bounds.width * 0.8, height: 208)
        .background(Color(.brandContrast))
        .cornerRadius(6)
        .padding(.horizontal)
    }
    
    internal static func == (lhs: Self, rhs: Self) -> Bool {
        lhs.id == rhs.id
    }
}

I am worries. Help me! Thank you.

  • Next can be helpful https://stackoverflow.com/a/63018486/12299030. – Asperi Jan 22 '21 at 04:29
  • 3
    I got one precondition failure by using randomly generated `Identifiable`. My view will be created by SwiftUI for 3 times after it is pushed and before it appears. The random Identifiable will make the view different every time, so it crashed (why?). Fixing the identifiable value resolves the issue. But if the view displays as the root view instead of being pushed, it will not crash. – Hai Feng Kao Jul 12 '21 at 19:42
  • 1
    I got another precondition failure by popping the view. The reason is I changed the view state when I pop out the view. Avoiding the change resolves the issue. I think SwiftUI is full of surprise and mystery. – Hai Feng Kao Jul 12 '21 at 19:46

1 Answers1

0

The answer by Hai Feng worked for me. I just removed the random id (UUID) from the Identifiable fixed the crash