ScrollView swiftUI 中的 VStack

问题描述 投票:0回答:1

我有视图,位于 ScrollView stackView 内部,内容在点击按钮后展开,然后我应该滚动此页面。在底部我有带有按钮的 HStack,上面有“RatingViews”。 我需要使最后一个 HStack 中的按钮始终位于底部,并且始终具有相同的缩进。扩展之前和之后。

它们应该距安全区域 8 偏移,距最后一个“评级视图”偏移 40。我该如何实现这一目标?

代码:

import SwiftUI

struct SH1ViewResult: View {
    @State var text: String = "long text long text long text long textlong text long textlong text long textlong text long textlong text long textlong text long textlong text long textlong text long textlong text long textlong text long textlong text long textlong text long textlong text long textlong text long textlong text long textlong text long textlong text long textlong text long textlong text long textlong text long textlong text long textlong text long textlong text long textlong text long textlong text long textlong text long textlong text long textlong text long textlong text long textlong text long textlong text long textlong text long textlong text long textlong text long textlong text long textlong text long textlong text long textlong text long textlong text long textlong text long textlong text long textlong text long textlong text long textlong text long textlong text long textlong text long textlong text long textlong text long textlong text long textlong text long textlong text long textlong text long textlong text long textlong text long textlong text long textlong text long textlong text long textlong text long text"
    @State var userVoice: Bool = false
    @State var isExpanded: Bool = false
    @State var score: Int = 69
    var quit: () -> Void

    var body: some View {
        GeometryReader { geometry in
            ScrollView {
                VStack {
                    Rectangle()
                        .background(Color.blue)
                        .frame(width: .infinity, height: 50)
                    VStack {
                        ScrollView {
                            Text("\(text)")
                                .padding([.top, .bottom, .leading, .trailing], 12)
                        }
                        .disabled(isExpanded)
                    }
                    .background(Color.green)
                    .frame(width: geometry.size.width - 32,
                           height: isExpanded ?
                        .infinity :
                            geometry.size.height * 0.40
                    )
                    .overlay(
                        VStack {
                            Spacer()
                            Image("Chevron")
                                .renderingMode(.template)
                                .resizable()
                                .frame(width: 8, height: 13)
                                .foregroundColor(Color.black)
                                .rotationEffect(.degrees(-90))
                                .padding(.bottom, 4)
                                .onTapGesture {
                                    isExpanded = true
                                }
                        }
                            .frame(width: geometry.size.width - 32, height: 40)
                            .background(
                                LinearGradient(gradient:
                                                Gradient(colors:
                                                            [Color.green,
                                                             Color.gray]),
                                               startPoint: .top,
                                               endPoint: .bottom
                                              )
                            )
                            .opacity(isExpanded ? 0 : 1),
                        alignment: .bottom
                    )
                    .cornerRadius(10)
                    HStack(spacing: 24) {
                        Button {
                            print("example sound")
                        } label: {
                            Image(systemName: "")
                                .resizable()
                                .frame(width: 108, height: 42)
                        }
                        Button {
                            print("uservoice")
                        } label: {
                            Image(systemName: "")
                                .resizable()
                                .frame(width: 108, height: 42)
                        }
                    }
                    .padding(.top, 16)
                    VStack {
                        RatingStarsView(score: .constant(55),
                                        labelIsShow: .constant(true)
                        )
                    }
                    .padding(.top, 16)
                    VStack {
                        HStack {
                            Spacer()
                            Text("first")
                                .frame(maxWidth: .infinity)
                            RatingStarsView(score: .constant(72),
                                            labelIsShow: .constant(false)
                            )
                            .frame(maxWidth: .infinity)
                            Spacer()
                        }
                        .padding(.bottom, 24)
                        .frame(width: geometry.size.width - 64, height: 30)
                        HStack {
                            Spacer()
                            Text("second")
                                .frame(maxWidth: .infinity)
                            RatingStarsView(score: .constant(85),
                                            labelIsShow: .constant(false)
                            )
                            .frame(maxWidth: .infinity)
                            Spacer()
                        }
                        .frame(width: geometry.size.width - 64, height: 30)
                    }
                    .padding(.top, 22)

                    Spacer()
                        .frame(height: 8)
                    HStack(spacing: 20) {
                        Button {
                            print("button")
                        }  label: {
                            Text("button 1")
                                .font(.system(size: 17, weight: .medium))
                                .frame(maxWidth: .infinity, maxHeight: 10)
                                .padding([.leading, .trailing], 16 )
                        }
                        .buttonStyle(LightGreenButton())
                        .disabled(userVoice ? true : false)
                        Button {
                            print("tapped next")
                        }  label: {
                            Text("button 2")
                                .font(.system(size: 17, weight: .medium))
                                .frame(maxWidth: .infinity, maxHeight: 10)
                                .padding([.leading, .trailing], 16)
                        }
                        .buttonStyle(FilledButton())
                        .disabled(userVoice ? true : false)
                    }
                    .padding([.leading, .trailing], 16)
                    .frame(width: geometry.size.width - 32)
                }
                .frame(height: isExpanded ? .infinity : geometry.size.height)
            }
            .scrollEnabled(isExpanded)
        }
    }
}

extension View {
    @ViewBuilder func scrollEnabled(_ enabled: Bool) -> some View {
        if enabled {
            self
        } else {
            simultaneousGesture(DragGesture(minimumDistance: 0),
                                including: .all)
        }
    }
}
swiftui scroll expand vstack
1个回答
0
投票

你可以在外侧使用vStack来使你的hstack底部像这样

var body: some View {
        VStack {
            --- existing code-------- // remove hstack from here and put outside
            Spacer()
            HStack(spacing: 20) {
                Button {
                    print("button")
                }  label: {
                    Text("button 1")
                        .font(.system(size: 17, weight: .medium))
                        .frame(maxWidth: .infinity, maxHeight: 10)
                        .padding([.leading, .trailing], 16 )
                }
                .buttonStyle(.automatic)
                .disabled(userVoice ? true : false)
                Button {
                    print("tapped next")
                }  label: {
                    Text("button 2")
                        .font(.system(size: 17, weight: .medium))
                        .frame(maxWidth: .infinity, maxHeight: 10)
                        .padding([.leading, .trailing], 16)
                }
                .buttonStyle(.bordered)
                .disabled(userVoice ? true : false)
            }
            .padding([.leading, .trailing], 16)
            .padding([.bottom, .top], 40)
        }
        
    }
© www.soinside.com 2019 - 2024. All rights reserved.