Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
262 views
in Technique[技术] by (71.8m points)

ios - Swift UI Remove Extra List Empty Cells without Navigation Controller

Swift UI - Xcode

Problem: I have extra cells when my list is initialized. However, unlike other posts I do not have a navigation view. Is it mandatory to have a NavigationView in order to remove the extra cells from my list.

I have tried to implement a Navigation View but im not sure if its mandatory and how to properly implement.

.navigationBarTitle("List")
.listStyle(GroupedListStyle())

I would like to start a new Text or UIButton directly below the last "Current" cell without extra white spaces.

enter image description here

var body: some View {


    VStack(alignment: .leading) {


        Image("covidImage")
            .resizable()
            .aspectRatio(contentMode: .fit)
            .cornerRadius(5)

        Text("COVID DATA")
            .font(.system(.title, design: .rounded))
            .bold()
            .lineLimit(3)
            .padding(.bottom, 3)
            .padding(.leading, 10)

        Text("Represented by Sate in the United States")
            .font(.subheadline)
            .foregroundColor(.secondary)
            .padding(.leading, 10)
            .padding(.bottom, 0)

        Text("Current State: CA")
        .font(.subheadline)
        .foregroundColor(.secondary)
        .padding(.leading, 10)
        .padding(.bottom, 10)

      //List to Initialize TableView Data
        List(covid) { covidData in
            Image(systemName: "photo")
                .padding()
            HStack {
                Text(covidData.dataTitle).frame(maxWidth: .infinity, alignment: .leading)

                Text(covidData.dataValue)
                    .font(.subheadline)
                .frame(maxWidth: .infinity, alignment: .trailing)
                    //.color(.gray)


            }


        }//END List


    }//END Original VStack



}//END Some View
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

They are not empty cells. The List just fills all available space and draws empty rows placeholders where there is no content. In your scenario is needed to limit height of List to its content.

Here is a solution. Tested with Xcode 11.4 / iOS 13.4

For better visibility let's separate your list into own view named CovidDataList, then here is in your provided body:

  //List to Initialize TableView Data
    CovidDataList(covid: self.covid)

    }//END List

Note1: The height of list updated in run-time so should be tested in running application (not in Preview)

Note2: I tested with replicated cover data model so some adapting might be needed to your code

struct CovidDataList: View {
    @Environment(.defaultMinListRowHeight) var minRowHeight

    let covid: [CovidData]
    @State private var listHeight = CGFloat.infinity

    var body: some View {
        List {
            ForEach(covid, id: .self) { covidData in
                HStack {
                    Image(systemName: "photo")
                        .padding()
                    HStack {
                        Text("Title").frame(maxWidth: .infinity, alignment: .leading)

                        Text("Value")
                            .font(.subheadline)
                            .frame(maxWidth: .infinity, alignment: .trailing)
                    }
                }
                .listRowInsets(EdgeInsets()).padding(.horizontal)
            }
            .anchorPreference(key: BoundsPreferenceKey.self, value: .bounds) { [$0] }
        }
        .backgroundPreferenceValue(BoundsPreferenceKey.self) { rects in
            GeometryReader { gp in
                self.updateListFrame(gp: gp, anchors: rects)
            }
        }.frame(maxHeight: listHeight)
    }

    private func updateListFrame(gp: GeometryProxy, anchors: [Anchor<CGRect>]) -> some View {
        let contentHeight = anchors.reduce(CGFloat.zero) { $0 + gp[$1].size.height }
        DispatchQueue.main.async {   // << required !!
            self.listHeight = max(contentHeight, self.minRowHeight * CGFloat(self.covid.count))
        }
        return Color.clear
    }
}

Note: BoundsPreferenceKey is taken from this my answer


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...