簡體   English   中英

一個 SwiftUI 視圖中的多個垂直滾動視圖

[英]Multiple vertical ScrollViews in one SwiftUI view

我正在嘗試實現一個包含三種不同數據類型的選項卡布局 LazyVGrid。 為此,我采用了 Single scrollView 並創建了多個 LazyVGrid 來容納這些數據。

我面臨的問題是,每當滾動選項卡 1 中的列表時,選項卡中的列表都會以相同的偏移量滾動。

我已經嘗試過兩種不同的解決方案-

  1. 將 LazyVGrid 創建為變量 - 我無法這樣做,因為它將擁有的數據屬於 ViewModel 並且 LazyVGrid 在實際示例中是一個單獨的視圖。
  2. 每次都使用 ScrollView - 我嘗試這樣做,但每次當前選擇的類型發生變化時,SwiftUI 都會強制 LazyVGrid 重新填充並從偏移量 0 開始顯示。

下面是我的代碼的樣子,如果有人能幫助我了解如何解決這個問題,那就太好了。

請找到我的代碼和當前輸出。 我希望當我切換選項卡並返回時,ScrollView 偏移量保持在我離開它的位置。

import SwiftUI

enum SearchType: String, CaseIterable {
    case movie = "Movies"
    case tv = "TV Shows"
    case people = "People"
}

struct SearchContainerView: View {
@ObservedObject var viewModel = SearchViewModel()
@State var currentSelectedSearchType: SearchType = .movie

let array: [String] = ["The", "above", "works", "great", "when", "you", "know", "where", "in", "the", "array", "the", "value" ,"is", "that", "is", "when" ,"you", "know", "its", "index", "value", "As", "the", "index", "values", "begin", "at" ,"0", "the" ,"second", "entry", "will", "be", "at", "index", "1"]
var body: some View {
    NavigationView {

        VStack {
            HStack {
                ForEach(SearchType.allCases, id: \.self) { type in
                    HStack {
                        Spacer()
                        Text(type.rawValue)
                            .font(.title3)
                            .onTapGesture {
                                self.currentSelectedSearchType = type
                            }
                        Spacer()
                    }
                    .padding(5)
                    .background(currentSelectedSearchType == type ? Color.gray : Color.clear)
                    .cornerRadius(10)
                }
                .background(Color.gray.opacity(0.5))
                .cornerRadius(10)
                .padding(.horizontal)
            }


            ScrollView {
                switch currentSelectedSearchType {
                case .movie:
                    LazyVGrid(columns: [
                        GridItem(.flexible()),
                        GridItem(.flexible()),
                        GridItem(.flexible())
                    ], content: {
                        ForEach(array, id: \.self) {
                            Text($0).font(.largeTitle).bold().frame(width: UIScreen.main.bounds.width / 3, height: 100, alignment: .center)
                        }
                    })
                case .tv:
                    LazyVGrid(columns: [
                        GridItem(.flexible()),
                        GridItem(.flexible()),
                        GridItem(.flexible())
                    ], content: {
                        ForEach(array, id: \.self) {
                            Text($0).font(.largeTitle).bold().frame(width: UIScreen.main.bounds.width / 3, height: 100, alignment: .center)
                        }
                    })
                case .people:
                    LazyVGrid(columns: [
                        GridItem(.flexible()),
                        GridItem(.flexible()),
                        GridItem(.flexible())
                    ], content: {
                        ForEach(array, id: \.self) {
                            Text($0).font(.largeTitle).bold().frame(width: UIScreen.main.bounds.width / 3, height: 100, alignment: .center)
                        }
                    })
                }
            }

        }
    }
}

}

電流輸出 -

 <img src="https://i.imgur.com/TgkIXYo.mp4" alt="this slowpoke moves" width="250" />

我了解您想在不同的 GridView 之間切換,但它們應該保持各自的滾動位置。

為了實現這一點,所有 3 個 ScollView 都必須保留在視圖層次結構中,否則——正如你所說——它們將被重建並失去它們的位置。

例如,您可以通過將所有內容放入 ZStack 並根據選擇控制不透明度(和活動)來做到這一點:

struct ContentView: View {
    //@ObservedObject var viewModel = SearchViewModel()
    @State var currentSelectedSearchType: SearchType = .movie
    
    var body: some View {
        NavigationView {
            VStack {
                HStack {
                    ForEach(SearchType.allCases, id: \.self) { type in
                        HStack {
                            Spacer()
                            Text(type.rawValue)
                                .font(.title3)
                                .onTapGesture {
                                    self.currentSelectedSearchType = type
                                }
                            Spacer()
                        }
                        .padding(5)
                        .background(currentSelectedSearchType == type ? Color.gray : Color.gray.opacity(0.5))
                        .cornerRadius(10)
                    }
                    .padding(.horizontal)
                }
                
                ZStack { // here
                    SearchResults(type: "Movie")
                        .opacity(currentSelectedSearchType == .movie ? 1 : 0)
                    
                    SearchResults(type: "Show")
                        .opacity(currentSelectedSearchType == .tv ? 1 : 0)

                    SearchResults(type: "Actor")
                        .opacity(currentSelectedSearchType == .people ? 1 : 0)

                }
            }
        }
    }
}

struct SearchResults: View {
    let type: String
    var body: some View {
        ScrollView {
            LazyVGrid(columns: [
                GridItem(.flexible()),
                GridItem(.flexible()),
                GridItem(.flexible())
            ], content: {
                ForEach(0..<30) {
                    Text("\(type) \($0)")
                        .font(.title).bold()
                        .frame(height: 100, alignment: .center)
                }
            })
        }
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM