SwiftUI 如何对齐大于屏幕宽度的视图 [英] SwiftUI How to align a view that's larger than screen width

查看:13
本文介绍了SwiftUI 如何对齐大于屏幕宽度的视图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 SwiftUI 绘制一个表格,该表格的行和列太多,无法适应屏幕的宽度/高度.在这种情况下,我无法将视图对齐为领先,但不知何故始终居中.我怎样才能将他们排在首位?这是绘制表格的视图:

I'm drawing a table using SwiftUI that has too many rows and columns to fit into the screen width / height. In this case, I cannot align the view as leading but is somehow always centered. How can I align them top leading? Here is the view that draws the table:

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:

And this is 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
    }
}

这就是它在应用程序中的样子.注意边缘不适合屏幕.即使我尝试在那里滚动,它也会反弹回来.

This is how it looks like in the app. Notice the edges don't fit inside the screen. Even if I try to scroll there, it just bounces back.

推荐答案

这里是一个可能的方法的演示(和改进的方向,因为我没有测试所有的情况和可能性)

Here is a demo of possible approach (and direction of improvements, because I did not test all cases and possibilities)

注意:如果您只选择一个 ScrollView 轴,它会自动进行内容对齐,否则现在我认为它很困惑,但无法进行配置.因此,以下可能被视为临时解决方法.

Note: if you select only one ScrollView axis it does content alignment automatically, otherwise it is now I assume confused, but does not have capability to be configured. So below might be considered as temporary workaround.

这个想法是通过 GeometryReader.global. 坐标空间中重新计算框架来读取网格内容偏移量并明确地减轻它.

The idea is to read grid content offset via GeometryReader recalculation of frame in .global. coordinate space and mitigate it explicitly.

还尝试根据设备方向使偏移无效和处理(可能不理想,但作为第一次尝试),因为它们是不同的.

Also there is a try to invalidate and handle offset depending on device orientation (probably not ideal, but as a first try), because they are different.

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

这篇关于SwiftUI 如何对齐大于屏幕宽度的视图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆