SwiftUI如何对齐超出屏幕宽度的视图

7

我正在使用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
    }
}

这是应用程序的显示效果。注意边缘不适合屏幕。即使我试图滚动,它也会反弹回来。
2个回答

2
这里提供了一种可能的方法演示(和改进方向,因为我没有测试所有情况和可能性)。
注意:如果您仅选择一个 ScrollView 轴,它会自动进行内容对齐,否则我认为它现在是混乱的,但无法配置。因此以下内容可以被视为暂时的解决方法。
我的想法是通过 GeometryReader 在 .global 坐标空间中重新计算框架的方式来读取网格内容偏移量,并明确地减轻它。
另外,试图根据设备方向使偏移量失效并处理它们(可能不是理想的,但作为第一次尝试),因为它们是不同的。
图片描述: https://istack.dev59.com/ttlIK.webp https://istack.dev59.com/a4ii2.webp
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))
        }
    }
}

这太棒了,解决了问题,谢谢!另外,我将您的 offset 重命名为 offsetX,并创建了一个 offsetY。因此,如果行和列都太大而无法适应视图,我也可以为 y 轴分配偏移量。 - berkabbasoglu
这个解决方案不起作用。在.offset(x:offset)中,更新的偏移变量从未被设置。它是一个状态变量,理论上应该可以工作,但实际上并没有工作。 - coolcool1994

1

经过几天的尝试,终于找到了最简单的解决方法。希望这可以帮到你。

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
        }
    }
}

enter image description here


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接