SideBar

public struct SideBar
extension SideBar: View
extension SideBar: _ViewEmptyChecking

SideBar: SwiftUI View

The SideBar SwiftUI view presents a expandable list of items using the SideBarListItem SwiftUI view. It has support for both edit and view modes. In edit mode, the listed data can be rearranged, and each item can be toggled as hidden. The hidden items are not shown in view mode.

This View should be used in NavigationSplitView as a side bar. How, in case you are NOT using the NavigationSplitView for the SideBar, you should observe the change of selected item using SideBar’s ‘selection’ property and handle follow-up logic by yourself. Also, you should set ‘isUsedInSplitView’ of SideBar to true and return EmptyView in ‘destination’ callback.

Usage

### Initialization:

Construct the data,, array of SideBarItemModel, for the expandable list that will be displayed in side bar.

 @State private var data: [SideBarItemModel] = [
     SideBarItemModel(title: "Root Item 0.1", icon: Image(systemName: "square.dashed"), filledIcon: Image(systemName: "square.dashed.inset.filled"), subtitle:
     "9,999+", accessoryIcon: Image(systemName: "clock"), children: nil),
     SideBarItemModel(title: "Root Item 0.4", icon: Image(systemName: "cloud.snow"), children: nil),
     SideBarItemModel(title: "Group 1", children: [
         SideBarItemModel(title: "Child Item 1.1", icon: Image(systemName: "square.and.pencil"), subtitle: "66", accessoryIcon: Image(systemName: "circle"),
       children: nil),
        SideBarItemModel(title: "Child Item 1.2", icon: Image(systemName: "square.and.pencil"), accessoryIcon: Image(systemName: "circle"), children: nil)
     ]),
     SideBarItemModel(title: "Group 2", children: [
         SideBarItemModel(title: "Child Item 2.1", icon: Image(systemName: "folder"), subtitle: "5", accessoryIcon: Image(systemName: "mail"), children: nil)
    ])
 ]

Initialize a SideBar with title, edit button, selected item destination view, the binding edit mode indicator, search query string, data, selected item and row item content

 @State private var isEditing = false
 @State private var queryString: String?
 @State private var selection: SideBarItemModel?

 SideBar(
     isEditing: $isEditing,
     queryString: $queryString,
     data: $data,
     selection: $selection,
     title: "SideBar",
     editButton: {
        // Or use SWiftUI EditButton() here directly if you don't need to check the changed data or customize the label for edit button: EditButton()
        Button(action: {
         if !self.isEditing {
             // Check the listItems
             for(_, item) in listItems.enumerated() {

             }
        }
    }, label: {Text(isEditing ? "Done" : "Edit")}) },
     destination: { item in
        DevDetailView(item)
    },
    item: { item in
        SideBarListItem(icon: item.wrappedValue.icon, filledIcon: item.wrappedValue.filledIcon, title: AttributedString(item.wrappedValue.title), subtitle:
         AttributedString(item.wrappedValue.subtitle ?? ""), accessoryIcon: item.wrappedValue.accessoryIcon, isOn: Binding<Bool>(get: {
         !item.wrappedValue.isInvisible }, set: { newValue in item.wrappedValue.isInvisible = !newValue}), selection: $selection, data: item.wrappedValue)
     }
 )

### Handle Search:

The binding property queryString is used to trigger searches. The .searchable modifier on NavigationSplitView can be used to bind the @State variable queryString which will bind to SideBar. At the same time, a UISearchBar can be initialized with the onAppear modifier and dismissed with the onDisappear modifier

NavigationSplitView {
      sideBar
}
.searchable(text: Binding<String>(get: { self.queryString ?? "" }, set: { newValue in self.queryString = newValue}), prompt: "Search")
.onAppear {
       let searchImage = UIImage(systemName: "magnifyingglass")?
           .withTintColor(UIColor(Color.preferredColor(.tertiaryLabel)), renderingMode: .alwaysOriginal)
           .applyingSymbolConfiguration(UIImage.SymbolConfiguration(weight: .semibold))
       UISearchBar.appearance().setImage(searchImage, for: .search, state: .normal)
}
.onDisappear {
       UISearchBar.appearance().setImage(nil, for: .search, state: .normal)
}