0

我有一个用于创建自动幻灯片的 tabview(页面样式)。由于某种奇怪的原因,每张幻灯片都没有分配给 currentIndex。计时器既不工作,也不使用 tabview 提供的默认点控件手动切换选项卡。

如果我将标签设置为 selectedIndex 选项卡视图将默认为第一张幻灯片。控制台没有错误。任何帮助是极大的赞赏!

struct HomeView: View {
    @EnvironmentObject private var hvm: HomeViewModel
    
    @State private var selectedFilter: String = "Popular"
    @State private var selectedMedia: MediaModelResult? = nil
    @State private var showDetailView: Bool = false
    @State private var currentIndex: Int = 0
    @State var isFilterSelected: Bool = true
    
    @Namespace var animation
    
    private let timer = Timer.publish(every: 3, on: .main, in: .common).autoconnect()
    
    var body: some View {
        NavigationView {
            ZStack {
                Color.theme.background.ignoresSafeArea()
                VStack {
                    header
                    VStack(alignment: .leading, spacing: 15) {
                        Text("Upcoming Movies")
                            .foregroundColor(Color.theme.secondaryAccent)
                            .font(.subheadline)
                            .padding(.leading, 15)
                        TabView(selection: $currentIndex) {
                            ForEach(hvm.upcomingFilms) { film in
                                MediaImageView(mediaPath: film, poster: false)
                                    .scaledToFill()
                                    .tag(film)
                            }
                        }
                        .tabViewStyle(PageTabViewStyle())
                        .clipShape(RoundedRectangle(cornerRadius: 5))
                        .padding(.horizontal, 15)
                        .frame(width: UIScreen.main.bounds.width, height: 180)
                        .onReceive(timer, perform: { _ in
                            withAnimation(.default) {
                                currentIndex = currentIndex < hvm.upcomingFilms.count ? currentIndex + 1 : 0
                            }
                        })
                    }
                    scrollViewContent
                }
            }
            .preferredColorScheme(.dark)
            .navigationBarHidden(true)
        }
    }
}
struct MediaImageView: View {
    @StateObject var mivm: MediaImageViewModel
    
    var poster: Bool
    
    init(mediaPath: MediaModelResult, poster: Bool) {
        self.poster = poster
        _mivm = StateObject(wrappedValue: MediaImageViewModel(mediaPath: mediaPath))
    }
    
    var body: some View {
        if poster {
            ZStack {
                if let image = mivm.poster {
                    Image(uiImage: image)
                        .resizable()
                        .scaledToFit()
                } else if mivm.isLoading {
                    ProgressView()
                }
            }
        } else {
            ZStack {
                if let image = mivm.backdrop {
                    Image(uiImage: image)
                        .resizable()
                } else if mivm.isLoading {
                    ProgressView()
                }
            }
        }
    }
}
class HomeViewModel: ObservableObject {
    @Published var tabBarImageNames = ["house", "rectangle.stack", "clock.arrow.circlepath", "magnifyingglass"]
    @Published var filterTitles = ["Popular Now", "Top Rated", "New"]
    @Published var popularFilms: [MediaModelResult] = []
    @Published var topRatedFilms: [MediaModelResult] = []
    @Published var upcomingFilms: [MediaModelResult] = []
    @Published var popularTV: [MediaModelResult] = []
    @Published var topRatedTV: [MediaModelResult] = []
    
    private let dataService = MediaDataService()
    private var cancellables = Set<AnyCancellable>()
    
    init() {
        addSubscribers()
    }
    
    func addSubscribers() {
        dataService.$popularFilms
            .sink { [weak self] (returnedFilms) in
                self?.popularFilms = returnedFilms
            }
            .store(in: &cancellables)
        dataService.$topRatedFilms
            .sink { [weak self] (returnedFilms) in
                self?.topRatedFilms = returnedFilms
            }
            .store(in: &cancellables)
        dataService.$upcomingFilms
            .sink { [weak self] (returnedFilms) in
                self?.upcomingFilms = returnedFilms
            }
            .store(in: &cancellables)
        dataService.$popularTV
            .sink { [weak self] (returnedFilms) in
                self?.popularTV = returnedFilms
            }
            .store(in: &cancellables)
        dataService.$topRatedTV
            .sink { [weak self] (returnedFilms) in
                self?.topRatedTV = returnedFilms
            }
            .store(in: &cancellables)
    }
}
4

1 回答 1

0

解决方案:

TabView(selection: $currentIndex) {
    ForEach(0..<hvm.upcomingFilms.count) { film in
       MediaImageView(mediaPath: hvm.upcomingFilms[film], poster: false)
           .scaledToFill()
    }
}
于 2021-08-16T21:28:33.490 回答