我试图实现一个包含三种不同数据类型的选项卡布局LazyVGrid.为此,我使用了一个scrollView并创建了多个LazyVGrid来容纳这些数据.

我面临的问题是,每当滚动选项卡1中的列表时,该选项卡中的列表都会以相同的偏移量滚动.

我已经try 过两种不同的解决方案-

  1. 将LazyVGrid创建为一个变量-我无法做到这一点,因为它将拥有的数据属于ViewModel,并且LazyVGrid在一个实际示例中是一个单独的视图.
  2. 每次都使用ScrollView-我try 过这样做,但每次当前 Select 的类型更改时,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都必须保持在视图层次 struct 中,否则,正如您所说的那样,它们将被重建并失go 其位置.

例如,您可以将所有内容放在ZStack中,并根据 Select 控制不透明度(和活动):

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)
                }
            })
        }
    }
}

Ios相关问答推荐

为什么Pushed View Controller在UIKit中具有导航控制器?

(Flutter)获取图像从图像拾取器保存和加载问题

更新@PersistableEnum时是否需要执行迁移块?

在许多UIButton中对齐文本,即使SF Symbols(或其他图像)具有不同的宽度?

从包含 5 个以上项目的自定义选项卡栏的导航视图中删除更多按钮

仅更改 AttributedString 的字符串(例如 UIButton 配置 attributeTitle)

当 .searchable 修饰符处于活动状态时,如何将变量设置为 false?

_SKStoreProductParameterAdNetworkSourceIdentifier未定义符号

当 Swift 枚举具有 any existential 作为其关联值之一时,我如何使它符合 `Equatable`?

var name: String 时 print(nil) 和 print(name) 的区别? = 无

SwiftUI 图像与下拉视图切换一起 skip

如何在 SwiftUI 中只显示一次随机数组的项目?

在向我的 struct 添加属性后获取线程 10:EXC_BAD_ACCESS (code=EXC_I386_GPFLT)

在iOS7半透明导航栏中获取正确的 colored颜色

如何用 Swift 圆化 UILabel 的边缘

UITableView 背景 colored颜色 在 iPad 上总是白色

Xcode:此时无法安装此应用程序.

iOS 7 圆形框架按钮

如果已安装,则重定向到应用程序,否则重定向到 App Store

具有两种不同字体大小的 NSAttributedString 示例?