You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 00:45:20