SwiftUI如何对齐大于屏幕宽度的视图
Posted
技术标签:
【中文标题】SwiftUI如何对齐大于屏幕宽度的视图【英文标题】:SwiftUI How to align a view that's larger than screen width 【发布时间】:2020-01-14 16:10:56 【问题描述】:我正在使用 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
这就是它在应用程序中的样子。注意边缘不适合屏幕。即使我尝试在那里滚动,它也会弹回来。
【问题讨论】:
【参考方案1】:这是一个可能的方法的演示(以及改进的方向,因为我没有测试所有的案例和可能性)
注意:如果您只选择一个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))
【讨论】:
这很好,解决了问题,谢谢!另外,我将您的offset
重命名为 offsetX
并创建了一个 offsetY
。所以我也可以为 y 轴分配一个偏移量,以防行和列都太大而无法进入视图。
此解决方案不起作用。更新的偏移变量永远不会在 .offset(x:offset) 中设置。它是一个状态变量,所以理论上它应该可以工作,但它不起作用。【参考方案2】:
经过几天的尝试,终于找到了一个最简单的解决方法。希望这能有所帮助。
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
【讨论】:
以上是关于SwiftUI如何对齐大于屏幕宽度的视图的主要内容,如果未能解决你的问题,请参考以下文章
Swift之深入解析SwiftUI布局如何自定义AlignmentGuides
SwiftUI - 如何将文本视图与另一个文本视图垂直对齐,以制作类似于正确对齐的表格?