SwiftUI Как выровнять вид, который больше ширины экрана - PullRequest
2 голосов
/ 14 января 2020

Я рисую таблицу, используя SwiftUI, в котором слишком много строк и столбцов, чтобы поместиться в ширину / высоту экрана. В этом случае я не могу выровнять вид как ведущий, но как-то всегда по центру. Как я могу выровнять их топ ведущих? Вот представление, что dr aws таблица:

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

Вот так это выглядит в приложении. Обратите внимание, что края не помещаются внутри экрана. Даже если я попытаюсь прокрутить туда, он просто отскочит назад.

Example screenshot

1 Ответ

1 голос
/ 14 января 2020

Вот демонстрация возможного подхода (и направления улучшений, потому что я не тестировал все варианты и возможности)

Примечание: если вы выбираете только одну ось ScrollView, выполняется выравнивание контента автоматически, в противном случае это теперь я предполагаю, что запутался, но не имеет возможности для настройки. Таким образом, ниже может рассматриваться как временный обходной путь.

Идея состоит в том, чтобы прочитать смещение содержимого сетки с помощью GeometryReader пересчета фрейма в .global. координатном пространстве и явно уменьшить его.

Также есть попытка аннулировать и обрабатывать смещение в зависимости от ориентации устройства (вероятно, не идеально, но в качестве первой попытки), потому что они разные.

enter image description here enter image description here

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))
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...