[英]SwiftUI How to align a view that's larger than screen width
我正在使用 SwiftUI 繪制一個表格,該表格具有太多的行和列,無法適應屏幕的寬度/高度。 在這種情況下,我無法將視圖對齊為領先,但總是居中。 我怎樣才能將它們排在首位? 這是繪制表格的視圖:
struct TableView: View {
let columnCount: Int = 9
let rowCount: Int = 14
var body: some View {
VStack(alignment: .leading, spacing: 20) {
ScrollView([.vertical, .horizontal], showsIndicators: false) {
GridStack(rows: self.rowCount, columns: self.columnCount) { row, col in
Text("ROW \(String(row)) COL \(String(col))")
.frame(width: 120)
}
}
}
}
}
這是 GridStack:
struct GridStack<Content: View>: View {
let rows: Int
let columns: Int
let content: (Int, Int) -> Content
var body: some View {
VStack(alignment: .leading) {
ForEach(0 ..< rows) { row in
HStack(alignment: .top) {
ForEach(0 ..< self.columns) { column in
self.content(row, column)
}
}
}
}
.padding([.top, .bottom], 20)
}
init(rows: Int, columns: Int, @ViewBuilder content: @escaping (Int, Int) -> Content) {
self.rows = rows
self.columns = columns
self.content = content
}
}
這就是它在應用程序中的樣子。 請注意邊緣不適合屏幕。 即使我嘗試在那里滾動,它也會反彈回來。
這是可能方法的演示(以及改進方向,因為我沒有測試所有案例和可能性)
注意:如果您只選擇一個ScrollView
軸,它會自動進行內容對齊,否則現在我認為它會混淆,但沒有配置能力。 因此,以下可能被視為臨時解決方法。
這個想法是通過GeometryReader
重新計算.global.
協調空間並顯式減輕它。
還有一個嘗試根據設備方向使偏移無效和處理(可能不理想,但作為第一次嘗試),因為它們是不同的。
import Combine
struct TableView: View {
let columnCount: Int = 9
let rowCount: Int = 14
@State private var offset: CGFloat = .zero
private let orientationPublisher = NotificationCenter.default.publisher(for: UIDevice.orientationDidChangeNotification)
var body: some View {
VStack(alignment: .leading, spacing: 20) {
ScrollView([.horizontal, .vertical], showsIndicators: false) {
GridStack(rows: self.rowCount, columns: self.columnCount) { row, col in
Text("ROW \(String(row)) COL \(String(col))")
.fixedSize()
.frame(width: 150)
}
.background(rectReader())
.offset(x: offset)
}
}
.onReceive(orientationPublisher) { _ in
self.offset = .zero
}
}
func rectReader() -> some View {
return GeometryReader { (geometry) -> AnyView in
let offset = -geometry.frame(in: .global).minX
if self.offset == .zero {
DispatchQueue.main.async {
self.offset = offset
}
}
return AnyView(Rectangle().fill(Color.clear))
}
}
}
經過幾天的嘗試,終於找到了一個最簡單的解決方法。 希望這能有所幫助。
func body(content: Content) -> some View {
GeometryReader { geo in
ScrollView([.horizontal, .vertical], showsIndicators: true) {
VStack {
ForEach(Range(1...10)) { x in
HStack {
ForEach(Range(1...10)) { y in
Text("\(x), \(y)")
.frame(width: 50, height: 20)
}
Spacer() // 🔑 1
}
}
Spacer() // 🔑 2
}.frame(minWidth: geo.size.width, minHeight: geo.size.height) // 🔑 3
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.