Sidebar Menu for macOS in SwiftUI
You need to make your enum case-iterable to use it as model in ForEach
, like
enum HostingBarCategories: Hashable, CaseIterable {
case Screen1
case Screen2
case Screen3
case Screen4
case Screen5
var string: String { String(describing: self) }
}
struct macOS_NavigationView: View {
@State private var selectedTab: HostingBarCategories = .Screen1
var body: some View {
NavigationView {
// SideBar Menu
List {
ForEach(HostingBarCategories.allCases, id: \.self) { screen in
NavigationLink(destination:
Text(screen.string)
.frame(maxWidth: .infinity, maxHeight: .infinity)
) {
Text("Link \(screen.string)")
}
}
}
.listStyle(SidebarListStyle())
// Primary View
Text("Select a menu...")
.frame(maxWidth: .infinity, maxHeight: .infinity)
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
}
}
Toggle Sidebar in SwiftUI NavigationView on macOS
Since macOS Big Sur beta 4 you can add default sidebar commands with SwiftUI 2.0.
var body: some Scene {
WindowGroup {
NavigationView {
Group {
SidebarView()
ContentView()
}
}
}
.commands {
SidebarCommands()
}
}
This code will add the "Toggle Sidebar" shortcut:
SidebarView code:
var body: some View {
List {
ForEach(0..<5) { index in
Text("\(index)")
}
}
.listStyle(SidebarListStyle())
}
How do I cleanly delete elements from a Sidebar List in SwiftUI on macOS
The reason this does not work is because your Destinationview to the right does not get updated when the State in your sidebar changes. Move the logic to the viewmodel and create a designated View that holds the UI for the Details.
move the selected var to your viewmodel:
class ModelData: ObservableObject {
@Published var myLinks = [
URL(string: "https://google.com")!,
URL(string: "https://apple.com")!,
URL(string: "https://amazon.com")!]
@Published var selected: URL?
}create a new View for destination:
struct DestinationView: View{
@EnvironmentObject var modelData: ModelData
var body: some View{
if let selected = modelData.selected{
Text("Viewing detailed data for: \(selected)")
}else{
Text("Choose a link")
}
}
}change navigationview destination:
NavigationLink(destination: DestinationView() ) {
Text(url.absoluteString)
}change your ondelete modifier:
if let selection = modelData.selected {
modelData.myLinks.remove(at: modelData.myLinks.firstIndex(of: selection)!)
}
modelData.selected = nil
SwiftUI macOS sidebar list-based navigation with pop
I solved it by making use of tag
, which allowed selection to work when there are arbitrary items in the List alongside dynamic ones:
struct Item: Identifiable {
let id: Int
let name: String
}
struct SidebarView: View {
var items: [String] = [Item(id: 1, name: "Item 1"), Item(id: 2, name: "Item 2")]
@State var selectionId: Int? = -1
var body: some View {
List {
NavigationLink(destination: SearchView(), tag: -1, selection: $selectionId) {
Text("Search")
}
NavigationLink(destination: CreateView(), tag: -2, selection: $selectionId) {
Text("Create New")
}
Section(header: Text("Item List")) {
ForEach(items, id: \.id) { item in
NavigationLink(destination: ViewItem(item), tag: item.id, selection: $selectionId) {
Text(item.name)
}
}
}
}
}
}
SwiftUI macOS app changes sidebar height on focus?
I figured it out with some help. Here is a working solution.
NavigationView {
List {
Section(header: Text("All projects")) {
ForEachStore(
self.store.scope(
state: { $0.projects },
action: AppAction.project(id:action:)),
content: { projectStore in
NavigationLink(
destination: ProjectView(store: projectStore).edgesIgnoringSafeArea(.all),
label: {
EditableListItemView(store: projectStore)
})
}
)
}
}
.overlay(SidebarBottomView(store: store), alignment: .bottom)
.frame(minWidth: 160, maxHeight: .infinity)
.listStyle(SidebarListStyle())
Text("Nothing here")
}
The key part is the .edgesIgnoringSafeArea(.all)
on the destination view. It also has to be specified at that "level" in the view hierarchy.
Placing the toggle sidebar button on the sidebar toolbar
try this:
ToolbarItem(placement: .primaryAction) {
Related Topics
Modifying an Array Passed as an Argument to a Function in Swift
Swift - Associated Types in Protocol with Where Clause
Argument of '#Selector' Does Not Refer to an '@Objc' Method, Property or Initializer
How to Get Frame Data in Apprtc iOS App for Video Modifications
How to Cast [Int8] to [Uint8] in Swift
Change the Font of a Datepicker
Generic and (Early) Binding in Swift 1.2
Why Use Class Only Protocols in Swift
Swiftui - How to Get Coordinate/Position of Clicked Button
How to Apply a Grace Time Using Rx
Why Can't I Use Self in a Func Swift
Ios15 Uttype Deprecations for Url-Extension
Google Sign-In via Firebase: Gidsignindelegate Does Not Conform to Viewcontroller
How to Sum the Numbers(Int16) of Stored Core Data - Swift 3
Compile Latex Code Using Swift
How to Pass Image Value to The Imageslideshow Using Swift
How to Fix Error: Abort Trap 6 (In Target 'Realmswift' from Project 'Pods')