Create Master Detail in Swift UI

Introduction

Creating an iPad (fixed landscape) Master Detail (SplitView) with SwiftUI was a lot of work. There is not much to describe and the content is simple as a result, but if you get hooked on it, you will not be able to achieve your purpose easily, so I will leave it as an article.

Display of master (left table view)

struct MasterDetail1View: View {
    @State private var fruits = ["Apple", "Banana", "Cherry", "Dragon Fruit"]
    @State private var selectedFruit = ""

    var body: some View {
        NavigationView {
            List {
                ForEach(fruits, id: \.self) { fruit in
                    Text(fruit)
                        .onTapGesture {
                            self.selectedFruit = fruit
                    }
                }
                .onAppear {
                    self.selectedFruit = "Apple"
                }
            }
            //Hide the navigation bar as you always need 2 columns
            .navigationBarHidden(true)
        }
   }
}

image.png

By default, the master (left table view) show / hide icon is displayed at the upper left corner. I want to always fix it in the master (left table view) display, so set .navigationBarHidden to true. image.png

Color the selected cell

struct MasterDetail2View: View {
    @State private var fruits = ["Apple", "Banana", "Cherry", "Dragon Fruit"]
    @State private var selectedFruit = ""

    var body: some View {
        NavigationView {
            List {
                ForEach(fruits, id: \.self) { fruit in
                    //Make one display area including the part other than the text (entire cell).
                    HStack{
                        Text(fruit)
                        Spacer()
                    }
                    //The shape is the entire rectangle.
                    .contentShape(Rectangle())
                    .onTapGesture {
                        self.selectedFruit = fruit
                    }
                    //Color the selected cell
                    .listRowBackground(self.selectedFruit == fruit ? Color.gray.opacity(0.25) : Color.clear)
                }
                .onAppear {
                    self.selectedFruit = "Apple"
                }
            }
            .navigationBarHidden(true)
        }
    }
}

Write .onTapGesture to get the tap event. Set the color with .listRowBackground. With only Text, you can get the tap event only in the text part. You can get the tap event for the entire cell by wrapping it in HStack together withSpacer ()and writing.contentShape (Rectangle ()). image.png

Detail display

struct MasterDetail3View: View {
    @State private var fruits = ["Apple", "Banana", "Cherry", "Dragon Fruit"]
    @State private var selectedFruit = ""

    var body: some View {
        NavigationView {
            List {
                ForEach(fruits, id: \.self) { fruit in
                    HStack{
                        Text(fruit)
                        Spacer()
                    }
                    .contentShape(Rectangle())
                    .onTapGesture {
                        self.selectedFruit = fruit
                    }
                    .listRowBackground(self.selectedFruit == fruit ? Color.gray.opacity(0.25) : Color.clear)
                }
                .onAppear {
                    self.selectedFruit = "Apple"
                }
            }
            .navigationBarHidden(true)
            //Fill the cell display format to the full width
            .listStyle(PlainListStyle())

            //Place Detail in the same hierarchy as List
            Detail(title: selectedFruit)
        }
    }
}

struct Detail: View {
    let title: String
    var body: some View {
        Text("\(self.title)").font(.system(size: 50)).frame(maxWidth: .infinity)
    }
}

You can display Detail on the right side just by writing View for Detail under List, but you can pad the display of the master (left table view) with that alone. image.png By describing .listStyle (PlainListStyle ()), it can be displayed as a master (left table view) with the full width. image.png

Source Code

Recommended Posts

Create Master Detail in Swift UI
Photo library in Swift UI
[Swift] Create UIButton class in code
Implementing side menus in Swift UI
Customize View with View Modifier in Swift UI
Create an HTML/XML generator in Swift (dynamicMemberLookup)
Swift UI 100 knocks
SKStoreReviewController implementation memo in Swift UI of iOS14
[Swift] Create an image selection UI with PhotoKit
Swift UI TextView placeholder
[Swift] Save Color to User Defaults in Swift UI (memo)
Division becomes 0 in Swift
Create UnsafeMutablePointer <UnsafeMutablePointer <Int8>?>! In Swift for C char ** hoge
Create JSON in Java
Starting with Swift Swift UI
Multidimensional array in Swift
List of devices that can be previewed in Swift UI
How to change BackgroundColor etc. of NavigationBar in Swift UI
Progress made with Swift UI
Create Azure Functions in Java
Implement Swift UITextField in code
[Swift UI] Use Map view