Таинственный интервал или заполнение элементов в VStack в ScrollView в SwiftUI - PullRequest
2 голосов
/ 31 января 2020

Я не понимаю, почему у меня есть посторонний вертикальный интервал между элементами в ForEach, который находится внутри VStack, который находится внутри ScrollView при использовании GeometryReader для визуализации пользовательской горизонтальной разделительной линии.

        ScrollView {
            ForEach(self.model1.elements, id: \.self) { element in
                VStack.init(alignment: .leading, spacing: 0) {
                    //                    Text("test") // image 3: works correctly
                    //                        .background(Color.blue)
                    GeometryReader { geometry in
                        Path { path in
                            path.move(to: .init(x: 0, y: 0))
                            path.addLine(to: .init(x: geometry.size.width, y: 0))
                        }
                        .strokedPath(.init(lineWidth: 1, dash: [1,2]))
                    }
//                    .frame(maxHeight: 1) // image 2: uncommenting this line doesn't fix the spacing
                    .foregroundColor(.red)
                    .background(Color.blue)

                    HStack {
                        Text("\(element.index+1)")
                            .font(.system(.caption, design: .rounded))
                            .frame(width: 32, alignment: .trailing)
                        Text(element.element)
                            .font(.system(.caption, design: .monospaced))
                            .frame(maxWidth:nil)
                        Spacer()
                    }
                    .frame(maxWidth:nil)
                    .background(Color.green)
                }
                .border(Color.red)
            }
        }

Приведенный выше код производит это: enter image description here

При .frame(maxHeight: 1) синяя заливка исчезла, но между последовательными * 1014 все еще есть пробел * s.
enter image description here

Я хочу, чтобы вертикальный интервал был таким же, как на этом изображении, ie 0. Это изображение достигается путем раскомментирования источника Text("test"), и комментируя код GeometryReader. enter image description here

Я использую Xcode 11.3.1 (11C504)

1 Ответ

2 голосов
/ 31 января 2020

Если я понимаю вашу конечную цель, это чтобы каждая строка была обведена пунктирной линией, без отступов между ними, например:

rows separated by red dotted lines

В этом случае, IMO, вы должны поместить линии в фоновом режиме. Например:

ScrollView {
    VStack(alignment: .leading) {
        ForEach(self.elements, id: \.self) { element in
            HStack {
                Text("\(element.index+1)")
                    .font(.system(.caption, design: .rounded))
                    .frame(width: 32, alignment: .trailing)
                Text(element.element)
                    .font(.system(.caption, design: .monospaced))
                Spacer()
            }
            .background(
                ZStack(alignment: .top) {
                    Color.green
                    GeometryReader { geometry in
                        Path { path in
                            path.move(to: .zero)
                            path.addLine(to: CGPoint(x: geometry.size.width, y: 0))
                        }
                        .strokedPath(StrokeStyle(lineWidth: 1, dash: [1,2]))
                        .foregroundColor(Color.red)
                    }
                }
            )
        }
    }
}

Ключевым моментом является то, что ScrollView не является вертикальным контейнером с накоплением. Он просто берет свое содержимое и делает его прокручиваемым. Его содержимое в вашем коде является ForEach, который генерирует представления; на самом деле он не намерен их выкладывать. Поэтому, когда вы объединяете ScrollView с ForEach, на самом деле ничто не отвечает за размещение представлений так, как вы хотите. Чтобы расположить представления вертикально, вам нужен VStack.

Вы также можете применить это к своей структуре, но добавив еще один VStack, и получите те же результаты:

ScrollView {
    VStack(spacing: 0) { // <---
        ForEach(self.elements, id: \.self) { element in
            VStack(alignment: .leading, spacing: 0) {
                GeometryReader { geometry in
                    Path { path in
                        path.move(to: .init(x: 0, y: 0))
                        path.addLine(to: .init(x: geometry.size.width, y: 0))
                    }
                    .strokedPath(.init(lineWidth: 1, dash: [1,2]))
                }
                .foregroundColor(.red)
                .frame(height: 1)

                HStack {
                    Text("\(element.index+1)")
                        .font(.system(.caption, design: .rounded))
                        .frame(width: 32, alignment: .trailing)
                    Text(element.element)
                        .font(.system(.caption, design: .monospaced))
                        .frame(maxWidth:nil)
                    Spacer()
                }
            }
            .background(Color.green) // <-- Moved
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...