In this post, we see how to expand a list item of a list. To do this is not complicated, the principle is simple when the user taps the row, we insert the current Item in a Set. The view used to show the current item change the visualization type if the current item is in the set of selected items.
Before starting copy the images: https://nicoladefilippo.com/wp-content/uploads/2021/05/blogger-336371_1920-1536×1024.jpg and https://nicoladefilippo.com/wp-content/uploads/2021/05/desk-593327_1920-1536×1024.jpg in your assets directory, renaming them blogger and desktop (you can use also other images if you prefer).
The final behaviour is:
Define the data model for the list:
struct Post: Identifiable, Hashable {
var id = UUID()
var title: String
var image: String
}
The view:
struct ExpandCardUIView: View {
@State private var selection: Set<Post> = []
var posts = [Post(title: "Post1", image: "blogger"), Post(title: "Post2", image: "desk"),
Post(title: "Post1", image: "blogger"), Post(title: "Post2", image: "desk"),
Post(title: "Post1", image: "blogger"), Post(title: "Post2", image: "desk"),
Post(title: "Post1", image: "blogger"), Post(title: "Post2", image: "desk"),
Post(title: "Post1", image: "blogger"), Post(title: "Post2", image: "desk"),
Post(title: "Post1", image: "blogger"), Post(title: "Post2", image: "desk"),
]
var body: some View {
NavigationView {
List(posts) { post in
RowView(post: post, isExpanded: self.selection.contains(post))
.onTapGesture {
self.selectDeselect(post)
}
}
.navigationBarTitle("I miei post")
}
}
private func selectDeselect(_ post: Post) {
if selection.contains(post) {
selection.remove(post)
} else {
selection.insert(post)
}
}
}
Take a look at the logic, at beginning define:
@State private var selection: Set<Post>
In this Set are added the Post when the user Tap the row. If the user re-tap the row, the Post is removed from the Set. This is done by calling the function selectDeselect.
The row is shown with:
struct RowView: View {
var post: Post
let isExpanded: Bool
var body: some View {
VStack {
HStack {
Text(post.title)
}
if isExpanded {
HStack {
BigRow(post:post)
}
}
}
}
}
The isEpanded is true when the selection (the Set) contains a post, in that case, the row shows also the BigRow, simply an image and another title in the body.
struct BigRow: View {
var post: Post
var body: some View {
VStack {
Image(post.image)
.resizable()
.aspectRatio(contentMode: .fit)
Text(post.title)
.fontWeight(.heavy)
.font(.system(.headline, design: .rounded))
}
}
}
Note: English is not my native language, so I’m sorry for some errors. I appreciate it if your correct me.






