NavigationLink干扰LazyVGrid列间距问题求助
问题描述
使用LazyVGrid实现三列布局(SF符号、分类文本、金额),尝试将文本与金额列设置为NavigationLink跳转至详情页后,金额列会紧贴文本列,布局错位。移除链接或仅给文本列添加链接时布局正常,尝试移除ScrollView、GeometryReader,添加.frame(maxWidth: .infinity)均无效果。
核心原因
错误地将第二列(文本)和第三列(金额)的内容放入同一个NavigationLink中,导致LazyVGrid将该NavigationLink视为单个网格项,仅占用第二列的宽度,两个文本在该列内横向挤压,第三列处于空置状态,最终引发布局错位。
修复方案
让LazyVGrid的三个子视图分别对应三列,为第二、第三列的内容各自包裹NavigationLink(两者指向同一详情页),确保每列的内容独立占据对应网格项的空间。
修改后的完整代码
Category 模型
// category model struct Category: Codable, Identifiable { var id = UUID() var catName: String var catBudget: Double var catPix: String }
CategoryModel 视图模型
class CategoryModel: ObservableObject { @Published var catItem = [ Category(catName: "Food", catBudget: 300.00, catPix: "cart"), Category(catName: "Lodging", catBudget: 1000.75, catPix: "bed.double.fill"), Category(catName: "Airplane", catBudget: 1700.25, catPix: "airplane"), Category(catName: "Train", catBudget: 250.40, catPix: "tram"), Category(catName: "Bus", catBudget: 10.26, catPix: "bus.fill") ] }
主视图 ContentView
struct ContentView: View { @ObservedObject var vm = CategoryModel() var columns: [GridItem] = [ GridItem(.fixed(50)), GridItem(.fixed(200)), GridItem(.flexible()) ] var body: some View { NavigationStack { GeometryReader { g in VStack (alignment: .leading) { Rectangle() .frame(height: g.size.height * 0.15) .foregroundStyle(.white) ScrollView { ForEach(vm.catItem) { item in Text("") .frame(maxWidth: .infinity) VStack { LazyVGrid( columns: columns, alignment: .leading, spacing: 20 ) { // 第一列:SF符号 Image(systemName: item.catPix) .imageScale(.large) // 第二列:分类文本(带跳转) NavigationLink { ShowDetail(item: item) } label: { Text(item.catName) .frame(maxWidth: .infinity, alignment: .leading) } // 第三列:金额(带跳转) NavigationLink { ShowDetail(item: item) } label: { let budget = item.catBudget.isNaN ? 0.0 : item.catBudget let gotBudget = budget.formatted(.currency(code: "USD").precision(.fractionLength(2))) Text(gotBudget) .frame(maxWidth: .infinity, alignment: .trailing) } } } .padding(.leading, 15) .foregroundStyle(.black) } } } } } } }
详情页 ShowDetail
struct ShowDetail: View { var item: Category var body: some View { VStack (alignment: .leading) { Text("Set \(item.catName) Budget") .font(Font.title3.bold()) } .padding() } }
额外优化说明
- 给文本和金额的
Text添加.frame(maxWidth: .infinity),可以让点击区域覆盖整个列宽,提升交互体验 - 金额列设置
.alignment: .trailing,符合常规的金额靠右布局习惯
内容的提问来源于stack exchange,提问作者Galen Smith
相关产品推荐
相关产品推荐

