Высота заполнения в scrollView в swiftUI - PullRequest
1 голос
/ 13 июля 2020

Я кодирую с использованием swiftUI, и у меня есть вертикальный scrollView (см. Скриншоты), а внутри этого scrollView у меня есть еще один горизонтальный scrollView, а ниже у меня есть VStack, высота которого должна быть заполните остальную часть экрана до нижней части вертикального scrollView, но я не могу заставить его работать.

Контент в вертикальном scrollView может быть больше, чем фактически оставшееся пространство в в некоторых случаях именно поэтому мне нужен scrollView, но в некоторых других случаях содержимое меньше, чем оставшееся пространство

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

    VStack {
        HeaderView
        
        ScrollView(.vertical, showsIndicators: false) {
            FriendsHorizontalScrollView()
            
            VStack {
                // I want this view to take all the remaining height left in the scrollView
                FullHeightView()
            }
            .frame(width: UIScreen.main.bounds.width)
        }
    }

То, что я получаю выглядит примерно так:

Скриншот того, что у меня есть

Что я хочу иметь:

Скриншот того, что я хочу

Я пробовал несколько решений, таких как использование geometryReader или установка .frame(maxHeight: .infinity) на VStack, но ничего не работает должным образом.

1 Ответ

0 голосов
/ 13 июля 2020

Вот демонстрация возможного подхода, основанного на предпочтениях просмотра (ViewHeightKey взято из моего этого решения. Протестировано с Xcode 12 / iOS 14.

демо

struct DemoLayoutInScrollView: View {
    @State private var height1: CGFloat = .zero
    @State private var height2: CGFloat = .zero
    var body: some View {
        VStack(spacing: 0) {
            HeaderView()

            GeometryReader { gp in
                ScrollView(.vertical, showsIndicators: false) {
                    VStack(spacing: 0) {
                        FriendsHorizontalScrollView()
                            .background(GeometryReader {
                                Color.clear
                                    .preference(key: ViewHeightKey.self, value: $0.frame(in: .local).size.height)
                            })
                            .onPreferenceChange(ViewHeightKey.self) { self.height1 = $0 }
                        VStack(spacing: 0) {
                            // I want this view to take all the remaining height left in the scrollView
                            FullHeightView()
                                .background(GeometryReader {
                                    Color.clear
                                        .preference(key: ViewHeightKey.self, value: $0.frame(in: .local).size.height)
                                })
                        }.frame(height: max(gp.size.height - self.height1, self.height2))
                        .background(Color.yellow)
                    }
                }
                .onPreferenceChange(ViewHeightKey.self) { self.height2 = $0 }
            }
        }.frame(maxWidth: .infinity)
    }
}

реплицированные вспомогательные представления (для тестирования)

struct FriendsHorizontalScrollView: View {
    var body: some View {
        Text("Horizontal Scroller")
            .frame(maxWidth: .infinity)
            .frame(height: 100)
            .background(Color.green)
    }
}

struct FullHeightView: View {
    var body: some View {
        ZStack {
            Color.red
            Text("Dynamic Content")
        }
        .frame(maxWidth: .infinity)
        .frame(height: 300)
    }
}

struct HeaderView: View {
    var body: some View {
        Rectangle().foregroundColor(.blue)
            .frame(height: 60)
            .overlay(Text("Header"))
    }
}
...