Having a traditional 'NavigationSplitView' setup, I am looking for a way to animate it the same as the sidebarView, where there is a button to toggle and it animates by sliding out from the right side of the view, however the closest I have gotten was manipulating the 'navigationSplitViewColumnWidth' but that always results in the view instantly appearing / disappearing.
I am using SwiftUI for a MacOS specific app.
Here is just a general idea of what I am currently doing, it is by no means a reflection of my real code but serves the purpose of this example.
struct ContentView: View {
@State private var columnWidth: CGFloat = 300
var body: some View {
NavigationSplitView {
List {
NavigationLink(destination: DetailView(item: "Item 1")) {
Text("Item 1")
}
NavigationLink(destination: DetailView(item: "Item 2")) {
Text("Item 2")
}
NavigationLink(destination: DetailView(item: "Item 3")) {
Text("Item 3")
}
}
.navigationTitle("Items")
} detail: {
VStack {
DetailView(item: "Select an item")
Button(action: toggleColumnWidth) {
Text(columnWidth == 300 ? "Collapse" : "Expand")
}
.padding()
}
}
.navigationSplitViewColumnWidth(columnWidth)
}
private func toggleColumnWidth() {
withAnimation {
columnWidth = columnWidth == 300 ? 0 : 300
}
}
}
struct DetailView: View {
var item: String
var body: some View {
Text("Detail view for \(item)")
.navigationTitle(item)
.padding()
}
}
@main
struct MyApp: App {
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
Post
Replies
Boosts
Views
Activity
Hello, I have a rudimentary list app that I have started, I am trying to establish a persistent sync with the iOS to the watch app. I am using swift data and have plans to use CloudKit too eventually. I made sure to recreate my data models and have them target both projects, but they only physically exist in the iOS folder.
// Models:
import Foundation
import SwiftData
@Model
class GroceryListModel {
@Attribute(.unique) var id: String
var title: String
var createdAt: Date
@Relationship var items: [GroceryItemModel]
init(id: String, title: String, createdAt: Date, items: [GroceryItemModel]
) {
self.id = id
self.title = title
self.createdAt = createdAt
self.items = items
}
}
import Foundation
import SwiftData
@Model
class GroceryItemModel {
@Attribute(.unique) var id: UUID
var name: String
var quantity: Int
// @Relationship var groceryList: [GroceryList]
init(id: UUID, name: String, quantity: Int) {
self.id = id
self.name = name
self.quantity = quantity
}
}
// for iOS, how I create an item:
//
// AddGroceryListView.swift
// Kitchen_Sync
//
//
import SwiftUI
import SwiftData
struct AddGroceryListView: View {
// Link to the persisted location
@Environment(\.modelContext) private var context
// Search & sort data
@Query(sort: \.id, order: .forward) var allItems: [GroceryItemModel]
// Props
@State private var title = ""
@State private var location = ""
// Render view
var body: some View {
// provide text fields to enter title and location, and a button to add the list
Text("Title: ")
Button("Save") {
createList()
}
}
// Creates persisted item for list
func createList() {
let list = GroceryListModel(id: UUID().uuidString, title: "blah", createdAt: .now, items: allItems
)
context.insert(list)
try? context.save()
}
}
#Preview {
AddGroceryListView()
}
// for Apple Watch version:
import SwiftUI
import SwiftData
struct GroceryListView: View {
@Environment(\.modelContext) private var context
@Query(sort: \.createdAt, order: .forward) var allGroceryLists: [GroceryListModel]
var body: some View {
// display list items and provide option to add new items
Text("Grocery List View")
ScrollView {
VStack {
ForEach(allGroceryLists) { item in
Text("an item")
}
}
}
}
}
#Preview {
GroceryListView()
}
// main app level for iOS:
//
// Kitchen_SyncApp.swift
// Kitchen_Sync
//
//
import SwiftUI
import SwiftData
@main
struct Kitchen_SyncApp: App {
var body: some Scene {
WindowGroup {
TabView {
groceryListView
groceryAddListView
}
.modelContainer(for: [
GroceryListModel.self,
GroceryItemModel.self
])
}
}
var groceryListView: some View {
NavigationStack {
GroceryListView()
.navigationTitle("List")
}
.tabItem { Label("List", systemImage: "list.bullet.indent") }
}
var groceryAddListView: some View {
NavigationStack {
AddGroceryListView()
.navigationTitle("Add")
}
.tabItem { Label("Add", systemImage: "plus") }
}
}
//#Preview {
// Kitchen_SyncApp()
//}
// Main app for watch:
//
// Kitchen_SyncApp.swift
// Kitchen_Sync Watch App
//
//
import SwiftUI
import SwiftData
@main
struct Kitchen_SyncWatchApp: App {
var body: some Scene {
WindowGroup {
TabView {
groceryListView
}
.modelContainer(for: [
GroceryListModel.self,
GroceryItemModel.self
])
}
}
var groceryListView: some View {
NavigationView {
GroceryListView()
.navigationTitle("List")
}
.tabItem { Label("List", systemImage: "list.bullet") }
}
}