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.
4 comments
A link to the source code would be nice. As for your English, I have seen others who are supposedly natively English that do not express themselves as well as you.
Also headers on the sections of this form would help, I’m guessing here.
Thanks for your comment, this week i’ll update this post with a link to the code (i’ll do the same for the next posts).
Great content! Keep up the good work!
Thanks!