.refreshable继续在导航堆栈视图中进行进一步的导航 – 如何停止它?

huangapple go评论64阅读模式
英文:

.refreshable continues to further NavigationStack views - how to stop it?

问题

我已在我的一个视图上设置了一个.refreshable修饰符(附加到一个VStack)。这个视图有导航链接到其他页面,但意外地在导航堆栈中的后续页面上仍然可以使用刷新功能。

也就是说,我仍然可以在从我声明.refreshable的第一个页面链接的任何页面上进行下拉刷新...

我希望.refreshable只适用于第一个页面,而不适用于其他页面。

我该如何做,以及为什么它一开始会这样行为?

第一个视图/页面上的代码如下:

VStack {
    NavigationStack {
        List {
            //包含一些列表元素的代码
        }
    }
}
.refreshable {
    await vm.loadUserStories(getUrl: url)
}
英文:

I have set a .refreshable modifier on one of my views (attached to a VStack). This view has NavigationLinks to other pages, but unexpectedly the refreshable still works in the next pages on the NavigationStack.

i.e. I can still pull to refresh in any page that was linked from the first page where I declared the .refreshable...

I would like this .refreshable to apply only to the first page, and not to the rest of the pages.

How do I do that, and why does it behave like that in the first place?

The code on the first View/page looks like this:

 VStack {
    NavigationStack {
        List {
            //Some code with list elements
        }
    }
}
.refreshable {
    await vm.loadUserStories(getUrl: url)

答案1

得分: 2

16.4将修复此错误

修复:应用于列表的可刷新修饰符将不再同时应用于列表或列表内容中的滚动视图。如果需要此行为,请重新应用可刷新修饰符到列表内容中。 (102052575)

iOS & iPadOS 16.4 Beta 发布说明

英文:

16.4 will fix this bug

> Fixed: Refreshable modifiers applied to lists will no longer also
> apply to lists or scroll views within the content of that list.
> Re-apply a refreshable modifier to the content of the list if this is
> desired behavior. (102052575)

iOS & iPadOS 16.4 Beta Release Notes

答案2

得分: 1

.refreshable文档

> 将此修饰符应用于视图,将视图环境中的refresh值设置为使用指定操作作为其处理程序的RefreshAction实例。

所以这个修饰符将你的闭包放入SwiftUI环境中。这就是为什么你所有的页面都在使用它。

接着往下看:

> 例如,在iOS和iPadOS上将此修饰符应用于List时,列表会启用标准的下拉刷新手势,以刷新列表内容。

所以答案是,将修饰符直接放在List上,而不是放在NavigationStack上。然后只有List的环境(及其子视图)将包含RefreshAction,而不会对其他页面可见。

VStack {
    NavigationStack {
        List {
            //一些包含列表元素的代码
        }
        .refreshable {
            await vm.loadUserStories(getUrl: url)
        }
    }
}
英文:

From the .refreshable documentation:

> Apply this modifier to a view to set the refresh value in the view’s environment to a RefreshAction instance that uses the specified action as its handler.

So the modifier puts your closure into the SwiftUI environment. That's why all your pages use it.

Reading on:

> For example, when you apply this modifier on iOS and iPadOS to a List, the list enables a standard pull-to-refresh gesture that refreshes the list contents.

So the answer is, put the modifier directly on the List instead of on the NavigationStack. Then only the environment of the List (and its subviews) will contain the RefreshAction, and it won't be visible to your other pages.

VStack {
    NavigationStack {
        List {
            //Some code with list elements
        }
        .refreshable {
            await vm.loadUserStories(getUrl: url)
        }
    }
}

答案3

得分: 0

很好,最好将NavigationStack放在第一个容器而不是VStack,就像这样:

struct ContentView: View {
   var body: some View {
    NavigationStack {
        VStack {
            List {
                NavigationLink(destination: someView) {
                    Text("你好,世界!")
                }
                NavigationLink(destination: Text("你好,世界!")) {
                    Text("你好,世界!")
                }
                NavigationLink(destination: Text("你好,世界!")) {
                    Text("你好,世界!")
                }
            }
            .refreshable {
                print("是的")
            }
        }
    }
}

var someView: some View {
    return VStack {
        List {
            Text("你好,世界!")
            Text("你好,世界!")
        }
    }
}
英文:

It's better to put the NavigationStack to be the first container not the VStack like this

struct ContentView: View {
   var body: some View {
    NavigationStack {
        VStack {
            List {
                NavigationLink(destination: someView) {
                    Text("Hello, world!")
                }
                NavigationLink(destination: Text("Hello, world!")) {
                    Text("Hello, world!")
                }
                NavigationLink(destination: Text("Hello, world!")) {
                    Text("Hello, world!")
                }
                
                
            }
            .refreshable {
                print("yes")
            }
        }
        
    }
}

  var someView: some View {
      return VStack {
          List {
              Text("Hello, world!")
              Text("Hello, world!")
          }
      }
  }
 
}

this should work, you can use NavigationView if you you want to support iOS versions less than iOS 16 but it's deprecated in iOS 16+

huangapple
  • 本文由 发表于 2023年2月24日 02:20:21
  • 转载请务必保留本文链接:https://go.coder-hub.com/75548817.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定