Home > Enterprise >  SwiftUI partial expandable List
SwiftUI partial expandable List

Time:06-08

What I want to achieve is a List that can be expanded partially. For instance, I have a list with 5 elements(rows) and the rest is hidden. Using a "show all" button I should be able to expand the list and see all the elements.

I know it is easily possible to expand/hide the whole section of the table, but that is not what I want. Any ideas of how to implement it?

CodePudding user response:

I just created this simple example and added some comments on the code.

import SwiftUI

/// Your model which should implement Identfiable.
struct MyItem: Identifiable {
    let id = UUID()
    let text: String
}

/// The expandable list view.
struct ExpandableList: View {
    
    /// All your items.
    private var items: [MyItem]
    /// The number of items you want to show when collapsed.
    private var visible: Int
    /// The visible items.
    private var visibleItems: [MyItem]
    
    // This controls the folding/unfolding of the list.
    @State var isExpanded = false
    
    /// Your initializer.
    init(items: [MyItem], visible: Int) {
        self.items = items
        self.visible = visible
        
        if visible < items.count {
            self.visibleItems = Array(items[0..<visible])
        } else {
            self.visibleItems = items
        }
    }
    
    var body: some View {
        
        List {
            // we iterate through the list
            ForEach( isExpanded ? items : visibleItems) { item in
                Text(item.text)
            }
            
            // we add a button on the right side after the list.
            // this could be at the beginning of the list too.
            HStack {
                Spacer()
                
                Button {
                    // the action to fold/unfold the list
                    isExpanded.toggle()
                    
                } label: {
                    if isExpanded {
                        Label("Show less", systemImage: "arrow.up")
                    } else {
                        Label("Show all", systemImage: "arrow.down")
                    }
                }
            }
        }
        // Adds some animation
        .animation(.easeOut, value: isExpanded)
    }
}

struct ContentView: View {
    
    // your data source
    var items = [MyItem(text: "A"), MyItem(text: "B"), MyItem(text: "C"), MyItem(text: "D"), MyItem(text: "E"), MyItem(text: "F"), MyItem(text: "G"), MyItem(text: "H"), MyItem(text: "I")]
    
    var body: some View {
        // the expandable list with the items (from your datasource) and the number of visible items.
        ExpandableList(items: items, visible: 4)
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

I hope it helps! :)

  • Related