首页 > 解决方案 > 在 swiftUI 中点击列表条目时呈现全屏视图

问题描述

我正在尝试完成我认为相对简单的事情,即当您点击列表中的项目时让视图显示全屏。此处显示的代码或多或少有效。但是,我必须准确地点击文本。点击空闲区域不会触发 onTap 事件。

示例代码:

struct ItemListView: View {
    var items: [Item]
    var titel: String
    
    @State private var selectedItem: Item?
    
    var body: some View {
        List(items) { item in
            ItemListCell(item: item)
                .onTapGesture {
                    selectedItem = item
                }
        }
        .navigationBarTitle(titel)
        .fullScreenCover(item: $selectedItem, onDismiss: nil) { item in
            ItemDetailView(item: item)
        }
    }
}

struct ItemListCell: View {
    var item: Item
    
    var body: some View {
        Text(String(item.id))
        Text(item.name)
    }
}

struct ItemDetailView: View {
    @Environment(\.presentationMode) var presentationMode
    
    var item: Item
    
    var body: some View {
        Text(String(item.id))
        Text(item.name)
        Button {
            presentationMode.wrappedValue.dismiss()
        } label: {
            Label("Close", systemImage: "xmark.circle")
        }
    }
}

我还查看了文档中的“支持列表中的选择”一章,但这仅在列表处于编辑模式时才有效。

是否有相当于 UIKit 的 swiftUI tableView(_:didSelectRowAt:)

标签: swiftui

解决方案


确保内容的框架占据了整个单元格。我在下面的示例中使用.frame(maxWidth: .infinity, alignment: .leading).

然后,添加一个contentShape修饰符,让 SwiftUI 知道将整个形状视为内容——否则,它往往会忽略空格。

struct ItemListCell: View {
    var item: Item
    
    var body: some View {
        VStack {
            Text(item.id)
            Text(item.name)
        }
        .frame(maxWidth: .infinity, alignment: .leading)
        .border(Color.green) //just for debugging to show the frame
        .contentShape(Rectangle())
    }
}

或者,如果您使用Button而不是onTapGesture,您基本上可以免费获得这一切:

List(items) { item in
    Button(action: {
        selectedItem = item
    }) {
        ItemListCell(item: item)
    }
}

最后,不,没有直接等价于tableView(_:didSelectRowAt:)


推荐阅读