gpt4 book ai didi

ios - SwiftUI: ScrollView 中的固定标题,在类似 Excel 的 View 中具有垂直和水平滚动

转载 作者:行者123 更新时间:2023-12-05 09:28:48 29 4
gpt4 key购买 nike

我使用多向 ScrollView 创建了一个类似 excel 的 View 。现在我想固定标题,不仅是列标题,还有行标题。请看下面的 gif:

enter image description here

我用来创建这个 View 的代码:

        ScrollView([.vertical, .horizontal]){
VStack(spacing: 0){
ForEach(0..<model.rows.count+1, id: \.self) {rowIndex in

HStack(spacing: 0) {
ForEach(0..<model.columns.count+1) { columnIndex in

if rowIndex == 0 && columnIndex == 0 {
Rectangle()
.fill(Color(UIColor(Color.white).withAlphaComponent(0.0)))
.frame(width: CGFloat(200).pixelsToPoints(), height: CGFloat(100).pixelsToPoints())
.padding([.leading, .trailing])
.border(width: 1, edges: [.bottom, .trailing], color: .blue)
} else if (rowIndex == 0 && columnIndex > 0) {
TitleText(
label: model.columns[columnIndex - 1].label,
columnWidth: CGFloat(columnWidth).pixelsToPoints(),
borderEgdes: [.top, .trailing, .bottom]
)
} else if (rowIndex > 0 && columnIndex == 0) {
TitleText(
label: model.rows[rowIndex - 1].label,
columnWidth: CGFloat(columnWidth).pixelsToPoints(),
borderEgdes: [.trailing, .bottom, .leading]
)
} else if (rowIndex > 0){
//text boxes
let column = model.columns[columnIndex - 1]
switch column.type {
case "Text":
MatrixTextField(keyboardType: .default)
case "Number":
MatrixTextField(keyboardType: .decimalPad)
case "RadioButton":
RadioButton()
case "Checkbox":
MatrixCheckbox()
default:
MatrixTextField(keyboardType: .default)
}

}

}
}

}
}
}
.frame(maxHeight: 500)

是否可以在此处固定列标题和行标题?

重要的是我只使用 VStack 和 HStack 而不是 LazyVStack 和 LazyHStack,因为我需要滚动时的平滑度,当我使用 Lazy 堆栈时,由于显而易见的原因它会抖动很多。所以不能在这里真正使用节标题。

我可以采用哪些其他方法?

最佳答案

这比预期的要复杂一些。您必须使用 .preferenceKey 来对齐所有三个 ScollView。这是一个工作示例:

enter image description here

struct ContentView: View {

let columns = 20
let rows = 30

@State private var offset = CGPoint.zero

var body: some View {

HStack(alignment: .top, spacing: 0) {

VStack(alignment: .leading, spacing: 0) {
// empty corner
Color.clear.frame(width: 70, height: 50)
ScrollView([.vertical]) {
rowsHeader
.offset(y: offset.y)
}
.disabled(true)
}
VStack(alignment: .leading, spacing: 0) {
ScrollView([.horizontal]) {
colsHeader
.offset(x: offset.x)
}
.disabled(true)

table
.coordinateSpace(name: "scroll")
}
}
.padding()
}

var colsHeader: some View {
HStack(alignment: .top, spacing: 0) {
ForEach(0..<columns) { col in
Text("COL \(col)")
.foregroundColor(.secondary)
.font(.caption)
.frame(width: 70, height: 50)
.border(Color.blue)
}
}
}

var rowsHeader: some View {
VStack(alignment: .leading, spacing: 0) {
ForEach(0..<rows) { row in
Text("ROW \(row)")
.foregroundColor(.secondary)
.font(.caption)
.frame(width: 70, height: 50)
.border(Color.blue)
}
}
}

var table: some View {
ScrollView([.vertical, .horizontal]) {
VStack(alignment: .leading, spacing: 0) {
ForEach(0..<rows) { row in
HStack(alignment: .top, spacing: 0) {
ForEach(0..<columns) { col in
// Cell
Text("(\(row), \(col))")
.frame(width: 70, height: 50)
.border(Color.blue)
.id("\(row)_\(col)")
}
}
}
}
.background( GeometryReader { geo in
Color.clear
.preference(key: ViewOffsetKey.self, value: geo.frame(in: .named("scroll")).origin)
})
.onPreferenceChange(ViewOffsetKey.self) { value in
print("offset >> \(value)")
offset = value
}
}
}

}

struct ViewOffsetKey: PreferenceKey {
typealias Value = CGPoint
static var defaultValue = CGPoint.zero
static func reduce(value: inout Value, nextValue: () -> Value) {
value.x += nextValue().x
value.y += nextValue().y
}
}

关于ios - SwiftUI: ScrollView 中的固定标题,在类似 Excel 的 View 中具有垂直和水平滚动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71122712/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com