Как я могу создать этот вид в SwiftUI? - PullRequest
1 голос
/ 30 апреля 2020

Я пытаюсь создать такой вид в SwiftUI (извините, он такой огромный): screen mockup

В частности, я пытаюсь создать прокручиваемый ряд меток / столбчатая диаграмма в верхней четверти экрана. Для меня это выглядит как ScrollView с горизонтальной прокруткой, содержащий некоторое число X barGraphItems, каждый из которых является VStack с меткой и цветным прямоугольником. Затем VStack поворачивается на 270 градусов.

Вот код, который у меня есть:

import SwiftUI

struct ContentView: View {
    var body: some View {
        HStack(alignment: .bottom, spacing: 0) {
            Spacer()
            VStack(alignment: .leading, spacing: 0) {
                Text("Demo")
                    .font(.caption)
                    .fontWeight(.bold)

                Rectangle().foregroundColor(.orange)
                    .frame(width: 84, height: 10)
            }
            .rotationEffect(Angle(degrees: 270.0))

            VStack(alignment: .leading, spacing: 0) {
                Text("Demo")
                    .font(.caption)
                    .fontWeight(.bold)

                Rectangle().foregroundColor(.orange)
                    .frame(width: 84, height: 10)
            }
            .rotationEffect(Angle(degrees: 270.0))

            VStack(alignment: .leading, spacing: 0) {
                Text("Demo")
                    .font(.caption)
                    .fontWeight(.bold)

                Rectangle().foregroundColor(.orange)
                    .frame(width: 84, height: 10)
            }
            .rotationEffect(Angle(degrees: 270.0))

            VStack(alignment: .leading, spacing: 0) {
                Text("Demo")
                    .font(.caption)
                    .fontWeight(.bold)

                Rectangle().foregroundColor(.orange)
                    .frame(width: 84, height: 10)
            }
            .rotationEffect(Angle(degrees: 270.0))

            VStack(alignment: .leading, spacing: 0) {
                Text("Demo")
                    .font(.caption)
                    .fontWeight(.bold)

                Rectangle().foregroundColor(.orange)
                    .frame(width: 84, height: 10)
            }
            .rotationEffect(Angle(degrees: 270.0))

        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

И вот что он производит (извините, он такой огромный): swiftui preview

Как я могу приблизить barGraphItems ближе друг к другу? Как добавить строку «Бюджет»? Как я могу сделать весь бизнес прокручиваемым без прокрутки строки бюджета?

Я думаю другие элементы на экране, которые я могу выяснить, но я весь день возился с этим виджетом гистограммы и я в тупике.

Ответы [ 2 ]

1 голос
/ 30 апреля 2020

Проблема с применением эффекта вращения к сложному контейнеру, имеющему много видов, заключается в том, что компоновка контейнера не изменяется, поэтому все другие виды, на которые влияет повернутый контейнер

Это выглядит более подходящим другим подходом. Идея состоит в том, чтобы в качестве прямоугольников отображались линейки графиков, где высота или прямоугольник показывают значения, а метка представляет собой преобразованное наложение для такого прямоугольника, поэтому прямоугольники формируют макет, и наложения не влияют ни на что (почти).

Протестировано с Xcode 11.4 / iOS 13.4

Примечание. Строка бюджета может быть добавлена ​​выше прокрутки графика, обернув оба в ZStack.

demo

demo2

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        VStack(alignment: .leading, spacing: 0) {
            Text("Title above").font(.largeTitle)
            ContentView()
            Text("comment below")
        }
    }
}


struct ContentView: View {
    var plotHeight: CGFloat = 120

    // test with different lenth labels
    let demos = ["Demo", "Demoos", "Demoooos", "Demooooooos"]

    var body: some View {
        ScrollView(.horizontal, showsIndicators: false) {
            HStack(alignment: .bottom, spacing: 24) {
                ForEach(0..<20) {_ in
                    Rectangle().foregroundColor(.orange)
                        .frame(width: 14, height: CGFloat.random(in: 0..<self.plotHeight)) // values for demo
                        .overlay(
                            Text(self.demos.randomElement()!) // values for demo
                                .font(.caption)
                                .fontWeight(.bold)
                                .fixedSize()
                                .rotationEffect(Angle(degrees: 270.0), anchor: .leading)
                                .offset(x: -8, y: 6)  // align as/if needed here
                        , alignment: .bottomLeading)
                }
            }
            .frame(height: plotHeight, alignment: .bottom)
            .padding(.leading) // required offset for first label in scrollview
        }
    }
}
0 голосов
/ 30 апреля 2020

Чтобы ответить на ваш первый вопрос: «Как я могу сделать barGraphItems ближе друг к другу?»

Я заменил ваш код следующим: () к тексту.

- Вы можете изменить количество баров, увеличив или уменьшив диапазон в моем для l oop. Это избавит вас от копирования и вставки одного и того же кода.

- Вы делали несколько VS-стэков, когда вам был нужен только один. Это решило проблему с интервалом, и теперь бары будут выходить слипшимися с нулевым интервалом, как определено.

Надеюсь, это поможет!

import SwiftUI

struct ContentView: View {
    var body: some View {
        HStack(alignment: .bottom, spacing: 0) {
            VStack(alignment: .leading, spacing: 0) {
                ForEach(0..<10) {_ in
                    Text("Demo")
                        .font(.caption)
                        .fontWeight(.bold)
                        .fixedSize()

                    Rectangle().foregroundColor(.orange)
                        .frame(width: 84, height: 10)
                }
            }
            .rotationEffect(Angle(degrees: 270.0))
        }
    }
}


struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...