FUISideBar

@available(iOS 14, *)
open class FUISideBar<Data>: UIView where Data: RandomAccessCollection,
                                          Data.Element: Identifiable & Hashable

A FUISideBar<Data> is a generic view that displaying data in an expandable list within a side bar.

Usage

Initialization:

Implement a data model for the expandable list that will be displayed in side bar.

struct BarItem: Identifiable, Hashable {
    let id = UUID()
    let title: String
    var icon: UIImage?
    var subtitle: String?
    var status: UIImage?
    let children: [BarItem]?

    func hash(into hasher: inout Hasher) {
        hasher.combine(self.id)
        hasher.combine(self.title)
    }

    static func == (lhs: BarItem, rhs: BarItem) -> Bool {
        lhs.id == rhs.id
    }

    init(title: String, icon: UIImage? = nil, subtitle: String? = nil, status: UIImage? = nil, children: [BarItem]? = nil) {
        self.title = title
        self.icon = icon
        self.subtitle = subtitle
        self.status = status
        self.children = children
    }
}

let items: [BarItem] = [
    BarItem(title: "Root Item 0.1", icon: UIImage(systemName: "cloud.snow"), subtitle: "9,999+", status: UIImage(systemName: "clock"), children: nil),
    BarItem(title: "Root Item 0.4", icon: UIImage(systemName: "cloud.snow"), children: nil),
    BarItem(title: "Group 1", children: [
        BarItem(title: "Child Item 1.1", icon: UIImage(systemName: "square.and.pencil"), subtitle: "66", status: UIImage(systemName: "circle"), children: nil),
        BarItem(title: "Child Item 1.2", icon: UIImage(systemName: "square.and.pencil"), status: UIImage(systemName: "circle"), children: nil)
    ]),
    BarItem(title: "Group 2", children: [
        BarItem(title: "Child Item 2.1", icon: UIImage(systemName: "folder"), subtitle: "5", status: UIImage(systemName: "mail"), children: nil)
    ])
]

Initialize an FUISideBar with the data model, a bindng of row content view, and the initially selected item.

let sidebar = FUISideBar(data: items,
                         children: \.children,
                         rowContent: { item in
                           FUISideBarListItem(icon: item.icon, title: item.title, subtitle: item.subtitle, accessoryIcon: item.status)
                         },
                         selectedItem: items.first)

Selection Handler:

A selectionDidChange closure may be used to custom the handling of an selected data element.

sidebar.selectionDidChange = { [weak self] item in
    self?.presentationDidChange?(item)
}
  • String for displaying subtitle in the side bar.

    Declaration

    Swift

    public private(set) var subtitle: String? { get }
  • Footer view of the side bar.

    Declaration

    Swift

    public private(set) var footer: UIView? { get }
  • Closure that defining behaviors once selection has been changed.

    Declaration

    Swift

    public var selectionDidChange: ((Data.Element?) -> Void)? { get set }
  • Public initializer for FUISideBar.

    Declaration

    Swift

    public init(subtitle: String? = nil,
                footer: UIView? = nil,
                data: Data,
                children: KeyPath<Data.Element, Data?>,
                rowContent: @escaping (Data.Element) -> UIView,
                selectedItem: Data.Element? = nil,
                selectionDidChange: ((Data.Element?) -> Void)? = nil)

    Parameters

    subtitle

    Subtitle for the side bar.

    footer

    Footer view for the side bar.

    data

    The data for constructing the expandable list within the side bar.

    children

    The key path to the optional property of a data element whose value indicates the children of that element.

    rowContent

    The data-binded closure which returns the view of each row in an expandable list.

    selectedItem

    Initially selected data element.

    selectionDidChange

    The closure that defines behaviors once a data element in the expandable list has been selected.