SwiftUI View appear differently in device and preview compare to view hierarchy capture

Viewed 130

I have a problem with SwiftUI

There was a issue

  1. yello view don't appear at first launch view
  2. move to home that makes app into background mode
  3. move to app (foreground)
  4. then yellow view appears

I captured view hierarchy in step 1. left view hierarchy capture, right device view capture (left is view hierarchy capture, right is simulator)

view hierarchy capture shows the yellow square but simulator didn't show yellow square

I checked the view breadscrum but both was same so I have no clue.

I'm sure this is not a networking problem.

There is two way to appear yellow square

  1. background -> foreground
  2. present alert -> dismiss alert

I'm not sure this is a framework bug or else.

Also, is there any API that I can print the swiftUI rendering request succeed or fail?

Thank you in advance and merry christmas!

enter image description here

(left is before yello square appear on simulator/ right is after yello square appear on simulator)

edit - add sample code

contentView

import SwiftUI

struct ContentView: View {
    
    @ObservedObject var viewModel : viewModel
    @ObservedObject var params : otherViewModel
    var body: some View {
            HorizontalScrollView(viewModel: viewModel, someParmas: params)
                .padding(.leading, 24)
                .frame(width: UIScreen.main.bounds.width, height:400)
                .background(Color.red)
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView(viewModel: viewModel(homeAPI: HomeAPI()), params: otherViewModel())
    }
}

import SwiftUI

struct HorizontalScrollView: View {
    
    @ObservedObject var viewModel: viewModel
    @ObservedObject var holder : otherViewModel
   
    private var homeHightlightRange: Range<Int> {
        return 0..<(viewModel.something?.somethingList?.count ?? 0)
    }
    
    init(viewModel: viewModel, someParmas: otherViewModel) {
        self.viewModel = viewModel
        self.holder = someParmas
    }
    
    var body: some View {
        VStack(spacing: 20) {
            HStack(spacing: 0) {
                Text("Merry christmas")
                    .font(.system(size: 24))
                    .foregroundColor(.white)
                    .bold()
                    .onTapGesture {
                        viewModel.getHighlight()
                    }
                Spacer()
            }
            
            ScrollView(.horizontal, showsIndicators: false, content: {
                HStack(alignment:.bottom, spacing: 14) {
                    ForEach(homeHightlightRange, id: \.self) { index in
                        Color.yellow.frame(width:200, height:300)
                    }
                }
            })
        }
        .frame(height: 339)
    }
}

struct HighlightView_Previews: PreviewProvider {
    static var previews: some View {
        HorizontalScrollView(viewModel: viewModel(homeAPI: HomeAPI()),someParmas: otherViewModel())
            .previewLayout(.sizeThatFits)
    }
}

homeHightlightRange is got from server via viewModel

1 Answers

I suppose that the solution is to add ScrollView conditionally on API results appear, like (not tested - typed here, so typos might be present)

if viewModel.something?.somethingList?.count != 0 {
    ScrollView(.horizontal, showsIndicators: false, content: {
        HStack(alignment:.bottom, spacing: 14) {
            ForEach(homeHightlightRange, id: \.self) { index in
                Color.yellow.frame(width:200, height:300)
            }
        }
    })
}
Related