首页 > 解决方案 > Swiftui:带有多个图像的粘性、弹性标题?

问题描述

在详细视图中,我想创建一个粘性的、可拉伸的标题,其中包含多个可以水平滚动的图像。

我有粘性,有弹性的标题。我还有多个可以使用 TabView (PageTabViewStyle()) 水平查看的图像。但是,当结合这两个功能时,我遇到了一个问题:每当整个标题被拉伸时,TabView 都会重置为数组中的第一个图像。我希望它留在屏幕上的图像上。

任何想法将不胜感激!

标签视图:

struct DetailGalleryView: View {
    let item: Item
    let gallery: [ItemImage] = Bundle.main.decode("gallery.json")

    var body: some View {
        let detailPhotos = gallery.filter{$0.type == item.id}
        
        ZStack {
            TabView{
                ForEach(detailPhotos) { photo in
                    ZStack(alignment: .bottomTrailing){
                        Image(photo.id)
                            .resizable()
                            .scaledToFill()
                            .frame(width: UIScreen.main.bounds.width)
                            .clipped()
                        Text("Photo: \(photo.licence)")
                            .padding(4)
                            .background(Color.black)
                            .font(.caption)
                            .foregroundColor(.white)
                            .offset(x: -5, y: -5)
                            .opacity(0.5)
                    }
            }
        }
        .edgesIgnoringSafeArea(.all)
        .tabViewStyle(PageTabViewStyle())
    }
  }
}

粘性标题:

struct StickyHeader<Content: View>: View {

    var minHeight: CGFloat
    var content: Content
    
    init(minHeight: CGFloat = 200, @ViewBuilder content: () -> Content) {
        self.minHeight = minHeight
        self.content = content()
    }
    
    var body: some View {
        GeometryReader { geo in
            if(geo.frame(in: .global).minY <= 0) {
                content
                    .frame(width: geo.size.width, height: geo.size.height, alignment: .center)
            } else {
                content
                    .offset(y: -geo.frame(in: .global).minY)
                    .frame(width: geo.size.width, height: geo.size.height + geo.frame(in: .global).minY)
            }
        }.frame(minHeight: minHeight)
    }
}

在详细视图正文中使用它:

// ...
  StickyHeader {
        DetailGalleryView(item: item)
  }
  .frame(minHeight: UIScreen.main.bounds.height/2.1)
// ...

标签: swiftuiheadergallery

解决方案


尝试保留选择TabView,例如

struct DetailGalleryView: View {
    let item: Item
    let gallery: [ItemImage] = Bundle.main.decode("gallery.json")
    
    @State private var selection:  ... // give it type of photo.id with some default value
    
    var body: some View {
        let detailPhotos = gallery.filter{$0.type == item.id}
        
        ZStack {
            TabView(selection: $selection){
                ForEach(detailPhotos) { photo in
                    ZStack(alignment: .bottomTrailing){
                        Image(photo.id)
                            .resizable()
                            .scaledToFill()
                            .frame(width: UIScreen.main.bounds.width)
                            .clipped()
                        Text("Photo: \(photo.licence)")
                            .padding(4)
                            .background(Color.black)
                            .font(.caption)
                            .foregroundColor(.white)
                            .offset(x: -5, y: -5)
                            .opacity(0.5)
                    }.tag(photo.id)
            }
        }
        .edgesIgnoringSafeArea(.all)
        .tabViewStyle(PageTabViewStyle())
    }
  }
}

推荐阅读