Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

items in ForEach iterating over each other

I created ListView which represents HStack with 5 elements:

var body: some View {
    
    GeometryReader { geo in
        HStack(alignment: .center) {
            renderHomeListItem(value: "\(title)", color: .black)
                .frame(width: geo.size.width * 0.3)
                
            renderHomeListItem(value: "\(confirmed)", color: Color(UIColor.systemRed))
                .frame(width: geo.size.width * 0.15)
            
            renderHomeListItem(value: "\(active)", color: Color(UIColor.systemBlue))
                .frame(width: geo.size.width * 0.15)
            
            renderHomeListItem(value: "\(recovered)", color: Color(UIColor.systemGreen))
                .frame(width: geo.size.width * 0.15)
            
            renderHomeListItem(value: "\(deaths)", color: Color(UIColor.systemGray))
                .frame(width: geo.size.width * 0.15)
        }
        .fixedSize()
    }
}

renderHomeListItem is representing one element in HStack:

@ViewBuilder
private func renderHomeListItem(value: String, color: Color) -> some View {
    
    Text(value)
        .padding()
        .commonFont(firstListItem == true ? .bold : .regular, style: .caption2)
        .frame(maxWidth: .infinity, maxHeight: .infinity)
        .foregroundColor(firstListItem == true ? color : .black)
        .background(colorScheme == .light ? Color(UIColor.systemGray5) : itemDarkModeBackground)
        .cornerRadius(5)
}

And I am calling ListView like this:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

@ViewBuilder
private func renderHomeList() -> some View {
    
    LazyVStack {
        HomeListItemView(title: homeViewModel.useCaseSelection == .worldwide ? "State" : "Date", confirmed: "C", active: "A", deaths: "D", recovered: "R")
        
        ForEach(homeViewModel.homeScreenDomainItem.listStats) { value in
            HomeListItemView(title: value.title,
                             confirmed: "\(value.confirmed.formatUsingAbbrevation())",
                             active: "\(value.active.formatUsingAbbrevation())",
                             deaths: "\(value.deaths.formatUsingAbbrevation())",
                             recovered: "\(value.recovered.formatUsingAbbrevation())")
        }
    }
    .padding()
}

Problem is that height of elements in ForEach is iterating over each other so I am getting something like this:

enter image description here

I tried to use padding() everywhere, but it is not answer.

>Solution :

That’s because of the GeometryReader.

The simplest solution, if it works in your layout, is to fix the size of the GeometryReader:

var body: some View {
    
    GeometryReader { geo in
        HStack(alignment: .center) {
            // renderHomeListItem x 5
        }
        .fixedSize()
    }

    // This will avoid the overlaps
    .frame(height: someValueHere)
}

Otherwise, if the height cannot be fixed, you need to move the GeometryReader to wrap the whole LazyVStack and then pass geo to HomeListItemView.

Like this (very schematic):

private func renderHomeList() -> some View {

  // Delete the GeometryReader from the HomeListItemView and move it here at the top
  GeometryReader { geo in    
    LazyVStack {

        // Create a new parameter in HomeListItemView to pass the geo variable
        HomeListItemView(geometry: geo, title: homeViewModel.useCaseSelection == .worldwide ? "State" : "Date", confirmed: "C", active: "A", deaths: "D", recovered: "R")
        
        ForEach(homeViewModel.homeScreenDomainItem.listStats) { value in

            // Create a new parameter in HomeListItemView to pass the geo variable
            HomeListItemView(geometry: geo, title: value.title,
                             confirmed: "\(value.confirmed.formatUsingAbbrevation())",
                             active: "\(value.active.formatUsingAbbrevation())",
                             deaths: "\(value.deaths.formatUsingAbbrevation())",
                             recovered: "\(value.recovered.formatUsingAbbrevation())")
        }
    }
    .padding()
  }
}
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading