Positionnement des vues avec GeometryReader dans SwiftUI
J'ai un ensemble de vues enfants (GridView1 et GridView2) dans un scrollview. Les vues enfants sont dans un VStack car j'en ai besoin l'une en dessous de l'autre. J'ai un GeometryReader enveloppant les vues enfants et chacune des vues enfants a un GeometryReader à l'intérieur. J'ai besoin du GeometryReader dans la vue enfant pour déterminer la largeur de l'espacement des colonnes dont j'ai besoin dans un LazyVGrid.
Le problème est que, en utilisant un GeometryReader dans les vues enfants, les deux vues enfants se superposent. J'ai essayé de définir la taille du cadre de la vue enfant mais cela limite le défilement vertical et ne me donne pas le bon résultat.
J'apprécierais toute aide pour résoudre ce problème.
ContentView:
struct ContentView: View {
var body: some View {
GeometryReader { geo in
ScrollView {
VStack(spacing: 20) {
GridView1()
GridView2()
}//.frame(minHeight: 0, maxHeight: .infinity)
}
}
.padding()
}
}
GridView1:
struct GridView1: View {
var body: some View {
GeometryReader { g in
let maxwidth = g.size.width/6 > 100 ? g.size.width/6 : 100
let columns = Array(repeating: GridItem(.flexible(minimum: 100, maximum: maxwidth), spacing: 0), count: 6)
ScrollView(.horizontal) {
LazyVGrid(columns: columns, alignment: .leading, spacing: 10, pinnedViews: [.sectionHeaders]) {
Section(header: Text("Grid 1").font(.title)) {
ForEach(0...200, id:\.self) { index in
Text("\(index)").frame(maxWidth: .infinity)
}
}
}
}
.background(Color.blue)
}
}
}
GridView2 (GridView1 et GridView2 sont essentiellement la même chose)
struct GridView2: View {
var body: some View {
GeometryReader { g in
let maxwidth = g.size.width/10 > 100 ? g.size.width/10 : 100
let columns = Array(repeating: GridItem(.flexible(minimum: 100, maximum: maxwidth), spacing: 0), count: 10)
ScrollView(.horizontal) {
LazyVGrid(columns: columns, alignment: .leading, spacing: 20, pinnedViews: [.sectionHeaders]) {
Section(header: Text("Grid 2").font(.title)) {
ForEach(1000...1200, id:\.self) { index in
ZStack {
Text("\(index)")
}
.frame(maxWidth: .infinity)
.background(Color.green)
}
}//.frame(minHeight: 0, maxHeight: .infinity)
}
}//.frame(minHeight: 1000, maxHeight: .infinity)
//.frame(maxWidth: .infinity, maxHeight: .infinity)
//.background(Color.red)
}
}
}
voici ce que j'attends:
Voici ce que je reçois actuellement. Comme vous pouvez le voir ci-dessous, les vues enfants se regroupent en haut.
Réponses
Au lieu d'utiliser interne GeometryReaderqui confond externe ScrollView, passez la largeur du haut GeometryReaderdans les grilles de sous-vues.
Voici la solution travaillée. Testé avec Xcode 12.1 / iOS 14.1
struct ContentView: View {
var body: some View {
GeometryReader { geo in
ScrollView {
VStack(spacing: 20) {
GridView1(width: geo.size.width)
GridView2(width: geo.size.width)
}
}
}
.padding()
}
}
struct GridView1: View {
let width: CGFloat
var body: some View {
let maxwidth = width/6 > 100 ? width/6 : 100
let columns = Array(repeating: GridItem(.flexible(minimum: 100, maximum: maxwidth), spacing: 0), count: 6)
ScrollView(.horizontal) {
LazyVGrid(columns: columns, alignment: .leading, spacing: 10, pinnedViews: [.sectionHeaders]) {
Section(header: Text("Grid 1").font(.title)) {
ForEach(0...200, id:\.self) { index in
Text("\(index)").frame(maxWidth: .infinity)
}
}
}
}
.background(Color.blue)
}
}
struct GridView2: View {
let width: CGFloat
var body: some View {
let maxwidth = width/10 > 100 ? width/10 : 100
let columns = Array(repeating: GridItem(.flexible(minimum: 100, maximum: maxwidth), spacing: 0), count: 10)
ScrollView(.horizontal) {
LazyVGrid(columns: columns, alignment: .leading, spacing: 20, pinnedViews: [.sectionHeaders]) {
Section(header: Text("Grid 2").font(.title)) {
ForEach(1000...1200, id:\.self) { index in
ZStack {
Text("\(index)")
}
.frame(maxWidth: .infinity)
.background(Color.green)
}
}
}
}
}
}