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.
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)
}
}
}
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
.
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 ())
.
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.
By describing .listStyle (PlainListStyle ())
, it can be displayed as a master (left table view) with the full width.
Recommended Posts