簡體   English   中英

SwiftUI如何對齊大於屏幕寬度的視圖

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM