Home > Back-end >  SwiftUI Make parent view stretch to fit child view
SwiftUI Make parent view stretch to fit child view

Time:11-01

I have a list of navigation views, where each item in the list has a title, 2 rows of sub text, and a partially filled rectangle. The rows look how I want, however the list items aren't big enough to fit the entire view, so they are flowing outside and overlapping each other. Here is a sample of what it looks like:

enter image description here

So how can i get the list items to expand to the size of their children?

Here is my code:

struct ItemDetials {
    let title: String
    let rowOne: String
    let rowTwo: String
    let stat: Double
    let maxOfStat: Double
    let color: UIColor
}

struct ItemDetailsRowView: View {
    var itemDetails: ItemDetials
    
    var body: some View {
        GeometryReader { geometry in
            ZStack(alignment: .leading) {
                Rectangle().frame(width: geometry.size.width * itemDetails.stat/itemDetails.maxOfStat,
                                  height: geometry.size.height)
                    .opacity(0.3)
                    .foregroundColor(Color(itemDetails.color))
            
                HStack {
                    VStack(alignment: .leading) {
                        Text(itemDetails.title)
                            .font(.system(size: 20))
                        Text(itemDetails.rowOne)
                            .font(.system(size: 12))
                            .foregroundColor(.gray)
                        Text(itemDetails.rowTwo)
                            .font(.system(size: 12))
                            .foregroundColor(.gray)
                    }
                }
            }
        }
    }
}

struct ItemDetailsRowView_Previews: PreviewProvider {
    static var previews: some View {
        let details: [ItemDetials] = [
            ItemDetials(
                title: "Test Title",
                rowOne: "Some info about row",
                rowTwo: "Some more info",
                stat: 0.6,
                maxOfStat: 1.0,
                color: .red
            ),
            ItemDetials(
                title: "Test Title 2",
                rowOne: "Some info about row 2",
                rowTwo: "Some more info 2",
                stat: 0.2,
                maxOfStat: 1.0,
                color: .green
            ),
            ItemDetials(
                title: "Test Title 3",
                rowOne: "Some info about row 3",
                rowTwo: "Some more info 3",
                stat: 0.8,
                maxOfStat: 1.0,
                color: .blue
            )
        ]
        
        VStack {
            let withIndex = details.enumerated().map({ $0 })
            List {
                ForEach(withIndex, id: \.element.title) { index, _ in
                    NavigationLink(destination: Text("Sup"), label: {
                        ItemDetailsRowView(itemDetails: details[index])
                    })
               }
            }
        }
    }
}

CodePudding user response:

Instead of wrapping the entire ZStack with the GeometryReader, wrap only the Rectangle where you need the size:

struct ItemDetailsRowView: View {
    var itemDetails: ItemDetials
    
    var body: some View {
        ZStack(alignment: .leading) {
            GeometryReader { geometry in
                Rectangle().frame(width: geometry.size.width * itemDetails.stat/itemDetails.maxOfStat,
                                  height: geometry.size.height)
                    .opacity(0.3)
                    .foregroundColor(Color(itemDetails.color))
            }
            
            HStack {
                VStack(alignment: .leading) {
                    Text(itemDetails.title)
                        .font(.system(size: 20))
                    Text(itemDetails.rowOne)
                        .font(.system(size: 12))
                        .foregroundColor(.gray)
                    Text(itemDetails.rowTwo)
                        .font(.system(size: 12))
                        .foregroundColor(.gray)
                }
                
            }
        }
    }
}

enter image description here

  • Related