SwiftUI实现嵌套水平滚动视图:点击分类显示子分类及返回按钮
实现SwiftUI嵌套水平滚动分类(带返回按钮)
针对你的需求,我们可以通过状态变量控制视图切换、添加子分类数据结构以及条件渲染二级滚动视图来实现。下面是具体的实现步骤和完整代码:
步骤1:定义分类与子分类数据
先给主分类关联对应的子分类,用字典存储更方便:
// 主分类数组 let categories = ["Clothing", "Shoes", "Accessories", "Bags"] // 主分类对应的子分类(可按需扩展) let subCategories: [String: [String]] = [ "Clothing": ["Tops", "Bottoms", "Dresses", "Outerwear", "Loungewear"], "Shoes": ["Sneakers", "Boots", "Sandals", "Heels"], "Accessories": [], "Bags": [] ]
步骤2:添加状态变量
新增状态变量控制视图状态和选中项:
@State private var selectedCat: String = "" // 控制是否显示二级子分类视图 @State private var showingSubCats: Bool = false // 当前选中的子分类 @State private var selectedSubCat: String = ""
步骤3:实现一级/二级视图的切换逻辑
用if-else条件渲染切换视图,二级视图中添加返回按钮:
ScrollViewReader { proxy in VStack { if showingSubCats { // 二级子分类滚动视图 ScrollView(.horizontal, showsIndicators: false) { LazyHStack(spacing: 5) { // 返回按钮 Button(action: { showingSubCats = false selectedSubCat = "" }) { HStack(spacing: 3) { Image(systemName: "chevron.left") Text("Back") } .font(.custom("AmericanTypewriter", fixedSize: 20)) } .padding(.horizontal, 10) .padding(.vertical, 5) .foregroundColor(.black) // 子分类按钮 ForEach(subCategories[selectedCat] ?? [], id: \.self) { subCat in Button(action: { selectedSubCat = subCat }) { Text(subCat) .font(.custom("AmericanTypewriter", fixedSize: 20)) } .padding(.horizontal, 10) .padding(.vertical, 5) .foregroundColor(.black) .background(selectedSubCat == subCat ? Color(UIColor(red: 143/255, green: 93/255, blue: 0/255, alpha: 1)).cornerRadius(40).opacity(0.7) : Color.white.cornerRadius(40).opacity(0)) } } .frame(maxWidth: .infinity, maxHeight: 50) .background(Color(UIColor(red: 255/255, green: 248/255, blue: 242/255, alpha: 0.6)).cornerRadius(40)) } .onChange(of: selectedSubCat) { _ in proxy.scrollTo(selectedSubCat) } } else { // 一级分类滚动视图(保留原有样式,修改点击逻辑) ScrollView(.horizontal, showsIndicators: false) { LazyHStack(spacing: 5) { ForEach(categories, id: \.self) { category in Button(action: { selectedCat = category // 判断当前分类是否有非空子分类,有则切换到二级视图 if !(subCategories[category]?.isEmpty ?? true) { showingSubCats = true } }) { Text(category) .font(.custom("AmericanTypewriter", fixedSize: 20)) } .padding(.horizontal, 10) .padding(.vertical, 5) .foregroundColor(.black) .background(selectedCat == category ? Color(UIColor(red: 143/255, green: 93/255, blue: 0/255, alpha: 1)).cornerRadius(40).opacity(0.7) : Color.white.cornerRadius(40).opacity(0)) } } .frame(maxWidth: .infinity, maxHeight: 50) .background(Color(UIColor(red: 255/255, green: 248/255, blue: 242/255, alpha: 0.6)).cornerRadius(40)) } .onChange(of: selectedCat) { _ in proxy.scrollTo(selectedCat) } } } }
关键逻辑说明
- 视图切换:通过
showingSubCats布尔值控制显示一级还是二级滚动视图 - 子分类触发:点击主分类时,判断该分类是否有非空子分类,有则切换到二级视图
- 返回功能:二级视图最左侧添加返回按钮,点击后重置状态回到一级视图
- 滚动定位:保留原有
ScrollViewReader的滚动定位逻辑,二级子分类也支持自动滚动到选中项
内容的提问来源于stack exchange,提问作者Soroushm
相关产品推荐
相关产品推荐

