Swift Ui - Different View(Layout) for first item of a List

Hi there!


I am relatively new to Swift. I want to accomplish that the first item of the weatherList is displayed with a different View.

Unfortunately I get this error in those 2 Lines (VStack and at ForEach-Line). If i put away the if i = 1 then and just use for normal layout for all listitems there is no error.

ERROR: Type '()' cannot conform to 'View'; only struct/enum/class types can conform to protocols


Here is my code:


var body: some View {

NavigationView {

VStack { // here first error

if self.model.error != nil {

Text(self.model.error!)

}

ForEach(0..<self.model.weatherList.count, id: \.self) { i in // here second error

if i == 1 {

NavigationLink(destination: DetailView(model: self.model.weatherList[i])) {

RowView(model: self.model.weatherList[i])

}

}

else{

NavigationLink(destination: DetailView(model: self.model.weatherList[i])) {

RowView(model: self.model.weatherList[i])

}

}

}

}

.navigationBarTitle(Text("Weather in " + UserSettings.instance.locationSetting))

.navigationBarItems(trailing:

Button(action: {

self.model.reload()

}) {

Image(systemName: "arrow.clockwise")

}

.disabled(model.reloading)

)

}

}


Would appreciate each advice. Thanks.

Answered by Claude31 in 414521022

First questions to check:

- why do you test i == 1 and not i == 0, for the first item ?

- i == 1 or else have exactly the same code. On purpose ?


Did you try something like this


var body: some View {
        NavigationView {
            VStack { // here first error
                if self.model.error != nil {
                    Text(self.model.error!)
                }
               // Handle the first separately, index 0
               NavigationLink(destination: DetailView(model: self.model.weatherList[0])) {
                      RowView(model: self.model.weatherList[0])               // Do you need an OtherRowView here ?
               }
               // Then loop starting at second (index 1)
                ForEach(1 ..< self.model.weatherList.count, id: \.self) { i in           // here second error
                        NavigationLink(destination: DetailView(model: self.model.weatherList[i])) {
                            RowView(model: self.model.weatherList[i])
                        }
                }
           
            }
            .navigationBarTitle(Text("Weather in " + UserSettings.instance.locationSetting))
            .navigationBarItems(trailing:
                Button(action: {
                    self.model.reload()
                }) {
                    Image(systemName: "arrow.clockwise")
                }
                .disabled(model.reloading)
            )
        }
    }
Accepted Answer

First questions to check:

- why do you test i == 1 and not i == 0, for the first item ?

- i == 1 or else have exactly the same code. On purpose ?


Did you try something like this


var body: some View {
        NavigationView {
            VStack { // here first error
                if self.model.error != nil {
                    Text(self.model.error!)
                }
               // Handle the first separately, index 0
               NavigationLink(destination: DetailView(model: self.model.weatherList[0])) {
                      RowView(model: self.model.weatherList[0])               // Do you need an OtherRowView here ?
               }
               // Then loop starting at second (index 1)
                ForEach(1 ..< self.model.weatherList.count, id: \.self) { i in           // here second error
                        NavigationLink(destination: DetailView(model: self.model.weatherList[i])) {
                            RowView(model: self.model.weatherList[i])
                        }
                }
           
            }
            .navigationBarTitle(Text("Weather in " + UserSettings.instance.locationSetting))
            .navigationBarItems(trailing:
                Button(action: {
                    self.model.reload()
                }) {
                    Image(systemName: "arrow.clockwise")
                }
                .disabled(model.reloading)
            )
        }
    }

Hi,

yeah that was a simple mistake of mine it should be 0 of course. Not so many hours of sleep.haha.


I tried ur solution problem was I fill the list in background and in the beginning its not filled. I just packed a if around there is no problem now.


I dont why but I was fixated on solving this in the same loop.


Thank you very much Claude.

Thanks for the feedback.


I had not the complete code with other views to test it, but it worked OK in a List set up.


Note: as you mark your own answer as the correct one, you should post the code, not just a comment. That will also let me see what was not OK in mine.


have a good day.

Swift Ui - Different View(Layout) for first item of a List
 
 
Q