1

我正在尝试使用 tabview 创建一个图像轮播并从 firebase 加载图片。不显示任何错误消息或代码 tabview 崩溃。请阐明这里出了什么问题。

struct HomeView : View{
var body : View{
    NavigationView{
        VStack{
            ScrollView{
                CategoryView(homeViewModel: homeViewModel)
                PosterView(homeViewModel: homeViewModel)
            }
        }
        .navigationBarTitleDisplayMode(.inline)
        .navigationBarTitle("")
    }
}

}



struct PosterView : View {
@StateObject var homeViewModel : HomeViewModel = HomeViewModel()
@State var currentIndex: Int = 0
var timer = Timer.publish(every: 3, on: .main, in: .common)

func next(){
    withAnimation{
        currentIndex = currentIndex < homeViewModel.posterList.count ? currentIndex + 
        1 : 0
    }
}


var body: some View{
    Divider()
    GeometryReader{ proxy in
    VStack{
        TabView(selection: $currentIndex){
            ForEach(homeViewModel.posterList){ item in
                let imgURL = homeViewModel.trendingImgDictionary[item.id ?? ""]
                AnimatedImage(url: URL(string: imgURL ?? ""))
            }
        }.tabViewStyle(PageTabViewStyle())
        .padding()
        .frame(width: proxy.size.width, height: proxy.size.height)
        .onReceive(timer) { _ in
            next()
        }
        .onTapGesture {
            print("Tapped")
        }
        
    }
    }
}
}

ViewModel:它包含两种从 Firebase 获取数据和图片的方法。这工作正常并且正在获取正确的数据。唯一的问题是在显示它时 tabview 崩溃而不显示任何错误消息。

class HomeViewModel : ObservableObject {

  @Published var posterList : [TrendingBanner] = []
  @Published var trendingImgDictionary : [String : String] = [:]

  init() {
    self.fetchTrendingList()
  }
   func fetchTrendingList()  {
    self.posterList.removeAll()
    firestore.collection(Constants.COL_TRENDING).addSnapshotListener { snapshot, error in
        guard let documents = snapshot?.documents else{
            print("No Documents found")
            return
        }
        self.posterList = documents.compactMap({ (queryDocumentSnapshot) -> TrendingBanner? in
            return try? queryDocumentSnapshot.data(as:TrendingBanner.self )
        })
        print("Trending list \(self.posterList.count)")
        print(self.posterList.first?.id)
        let _ = self.posterList.map{ item in
            self.LoadTrendingImageFromFirebase(id: item.id ?? "")
        }
    }
}


 func LoadTrendingImageFromFirebase(id : String) {

    let storageRef = storageRef.reference().child("trending/\(id)/\(id).png")
    storageRef.downloadURL { (url, error) in
        if error != nil {
            print((error?.localizedDescription)!)
            return
        }
        self.trendingImgDictionary[id] = url!.absoluteString
        print("Trending img \(self.trendingImgDictionary)")
    }
}
4

2 回答 2

1

如果你打开 SwiftUI 模块源代码,你会看到顶部的注释TabView

Text选项卡视图仅支持类型为 、Image或图像后跟文本的选项卡项。传递任何其他类型的视图会导致可见但为空的选项卡项。

您正在使用AnimatedImage可能不打算由TabView.

更新 我创建了一个库,它释放了 SwiftUI _PageView,它可以用来构建一个漂亮的标签栏。检查我的故事

于 2021-08-11T19:44:26.437 回答
0

最近在运行 iOS 14.5..<15 的设备上遇到了同样的问题。添加.id()修饰符TabView解决它。例子:

TabView(selection: $currentIndex) {
    ForEach(homeViewModel.posterList) { item in
        content(for: item)
    }
}
.tabViewStyle(PageTabViewStyle())
.id(homeViewModel.posterList.count)
于 2022-02-19T09:56:50.970 回答