使用 ScrollView 和 LazyHStack 实现可变高度内容的 SwiftUI 轮播

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

我正在使用

ScrollView
LazyHStack
创建水平轮播。

我想要达到的目标是这样的:

SwiftUI Carousel ScrollView LazyHStack variable height

我想要的是:

  1. 具有相同宽度和高度的图像
  2. 图像下方的文字可以是 1,2 或 3 行
  3. 图像在对齐方面应位于同一行
  4. 第一行文本应在同一行开始对齐

到目前为止我能够实现的是:

SwiftUI Carousel ScrollView HStack variable size

如您所见,图像未对齐,文本也因此未对齐。

这是我的代码

轮播:

struct CarouselView<Content: View>: View {
    let content: Content
    @State private var currentIndex = 0
    @State private var contentSize: CGSize = .zero
    
    private let showsIndicators: Bool
    private let spacing: CGFloat
    private let shouldSnap: Bool
    
    init(showsIndicators: Bool = true,
         spacing: CGFloat = .zero,
         shouldSnap: Bool = false,
         @ViewBuilder content: @escaping () -> Content) {
        self.content = content()
        self.showsIndicators = showsIndicators
        self.spacing = spacing
        self.shouldSnap = shouldSnap
    }
    
    var body: some View {
        ScrollView(.horizontal, showsIndicators: showsIndicators) {
            LazyHStack(spacing: spacing) {
                content
            }.apply {
                if #available(iOS 17.0, *), shouldSnap {
                    $0.scrollTargetLayout()
                } else {
                    $0
                }
            }
        }
        .apply {
            if #available(iOS 17.0, *), shouldSnap {
                $0.scrollTargetBehavior(.viewAligned)
            } else {
                $0
            }
        }
    }
}

extension View {
    func apply<V: View>(@ViewBuilder _ block: (Self) -> V) -> V { block(self) }
}

然后我像这样使用轮播:

struct ContentView: View {
    
    let imagesNames = ["img-1", "img-2", "img-3", "img-4"]
    let numberOfLines = [2, 1, 3, 2]
    
    var body: some View {
        
        VStack(spacing: 40) {
            continuousCarousel
        }
        
    }
    
    private var continuousCarousel: some View {
        CarouselView(showsIndicators: true,
                     spacing: 20) {
            ForEach(0 ..< imagesNames.count, id: \.self) { index in
                createImageTile(with: imagesNames[index],
                                height: 70,
                                numberOfLines: numberOfLines[index])
            }
        }
    }
    
    private func createImageTile(with image: String,
                                 height: CGFloat,
                                 numberOfLines: Int) -> some View {
        VStack(spacing: .zero) {
            Image(image)
                .resizable()
                .cornerRadius(30)
                .scaledToFit()
                .aspectRatio(contentMode: .fill)
                .frame(width: 200, height: 100)
                .padding(.bottom, 30)
            
            Text("Headline")
                .bold()
                .padding(.bottom, 10)
            
            ForEach(0 ..< numberOfLines, id: \.self) { _ in
                Text("Some description here")
                    .padding(.bottom, 5)
            }
        }
    }
}

我觉得在某处应用对齐或垫片可能会解决这个问题,但我不知道在哪里。

在我的

lazyHStack
上应用底部对齐不起作用,因为它将主要内容区域移动到滚动视图的底部。

我怎样才能实现我所需要的?

ios swift swiftui swiftui-scrollview lazyhstack
1个回答
0
投票

你可以试试

    VStack(spacing: .zero) {
        Image(image)
            .resizable()
            .cornerRadius(30)
            .scaledToFit()
            .aspectRatio(contentMode: .fill)
            .frame(width: 200, height: 100)
            .padding(.bottom, 30)
        HStach {
        Text("Headline")
            .bold()
            .padding(.bottom, 10)
        
        ForEach(0 ..< numberOfLines, id: \.self) { _ in
            Text("Some description here")
                .padding(.bottom, 5)
        }
        Spacer()
        }
        Spacer()
    }
© www.soinside.com 2019 - 2024. All rights reserved.