SwiftUI如何对齐大于屏幕宽度的视图 [英] SwiftUI How to align a view that's larger than screen width
问题描述
我正在使用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屋!