首页 > 解决方案 > 如何以编程方式按行内容导航列表?

问题描述

我有一个Listinside NavigationView,其中每个视图下List都应该附加可导航元素(封面图像、用户头像+名称等)。例如,单击封面图像导航到视图 A,而单击用户的名称/头像导航到视图B. 遗憾的是,在所有情况下,整个列表元素都是可点击的,并且没有授予预期的行为。

起初,我尝试将我的内容包装在一个NavigationLink.

NavigationLink(destination: Text("Media"), tag: .media, selection: $selection) {
    WebImage(url: URL(string: activity.media?.coverImage?.extraLarge ?? ""))
        .resizable()
        .placeholder { color }
        .cornerRadius(8)
        .frame(width: 90, height: 135)
}

这会导致出现一个箭头,指示视图对于用户来说是可导航的,但在这种情况下是不需要的。它也不必要地从视图中占用了大量空间。

我的下一个尝试是将视图包装NavigationLink在一个ZStack.

ZStack {
    NavigationLink(destination: Text("Media"), tag: .media, selection: $selection) {
        EmptyView()
    }.hidden()

    WebImage(url: URL(string: activity.media?.coverImage?.extraLarge ?? ""))
        .resizable()
        .placeholder { color }
        .cornerRadius(8)
}.frame(width: 90, height: 135)

.hidden()修改器应用于 以NavigationLink防止在图像透明时出现箭头。尽管此解决方案既隐藏了箭头又清理了多余的空间,但存在两个问题:

  1. 整个列表元素仍然是可点击的。
  2. ZStack被修饰符覆盖的A.frame需要我知道我想要使它有多大。用户的姓名和头像视图不能轻易克服这个困境。

第三,我尝试将视图包装在Button标签是封面图像的位置,并且操作是更改selection为以编程方式导航,但这带来了#1的间距问题以及列表元素可点击的整体问题。

后来我发现了一种解决方案,可以减少我之前遇到的问题,但带来了一个问题。为了理解它,这就是我的主要活动视图的样子:

NavigationView {
    List(viewModel.activities) { activity in
        ActivitySelectionView(activity: activity, selection: $selection)
    }.navigationTitle("Activity Feed")
}.onAppear {
    viewModel.fetchActivities()
}

通过封装List(...) {...}aScrollView并更改List为 a ForEach,我能够产生我想要的输出:元素内的可点击视图,点击它时封面图像变亮,而不是列表元素整体变暗直到松开,等等.

但是,这不是一个列表。不好看,在其他平台上也不会好看(这是一个iOS项目)。例如,此代码不像列表那样尊重边缘。它也不包括分隔符,但Divider结构可以提供帮助。我觉得这不是解决这个问题的正确方法。

总而言之,如何在列表尊重元素内的哪些视图可导航List的地方创建一个内部?NavigationView

标签: iosswiftswiftui

解决方案


我为我的问题找到了一个优雅的解决方案,所以我想与将来可能偶然发现这个问题的人分享。

您需要ScrollViewList {...}某处使用 a 。在ScrollView块中,非常适合使列表单元格中的某些元素可导航。

NavigationView {
  List(1..<11) { num in
    ScrollView {
      Text("\(num)!")

      NavigationLink(destination: Text("Number: \(num)")) {
        Text("Click me")
      }
    }
  }
}

推荐阅读