Định vị chế độ xem bằng GeometryReader trong SwiftUI
Tôi có một tập hợp các chế độ xem con (GridView1 và GridView2) trong chế độ xem cuộn. Các khung nhìn con nằm trong VStack vì tôi cần chúng bên dưới cái kia. Tôi có một GeometryReader bao bọc các khung nhìn con và mỗi khung nhìn con đều có một GeometryReader bên trong chúng. Tôi cần GeometryReader bên trong chế độ xem con để xác định độ rộng của khoảng cách cột mà tôi cần trong LazyVGrid.
Vấn đề là, việc sử dụng GeometryReader bên trong chế độ xem Con gây ra hai chế độ xem con chồng lên nhau. Tôi đã cố gắng đặt kích thước khung hình của chế độ xem con nhưng điều đó hạn chế việc cuộn dọc và không cho tôi kết quả phù hợp.
Tôi sẽ đánh giá cao bất kỳ sự giúp đỡ nào trong việc giải quyết vấn đề này.
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 và GridView2 về cơ bản giống nhau)
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)
}
}
}
đây là những gì tôi đang mong đợi:
Đây là những gì tôi hiện đang nhận được. Như bạn có thể thấy bên dưới, các chế độ xem con đang chụm lại ở trên cùng.
Trả lời
Thay vì sử dụng nội bộ GeometryReadergây nhầm lẫn với bên ngoài ScrollView, hãy chuyển chiều rộng từ trên GeometryReaderxuống vào lưới chế độ xem phụ.
Đây là giải pháp làm việc. Đã thử nghiệm với 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)
}
}
}
}
}
}