英文:
How to preview nested ScrollView from picking up refreshable modifier in SwiftUI
问题
如果我使父级的ScrollView可刷新,任何其他嵌套的ScrollView也将执行相同的可刷新操作。有没有办法阻止这种行为?这里是一个示例。
struct ContentView: View {
@State var showSheet = false
var body: some View {
ScrollView {
VStack {
Image(systemName: "globe")
.imageScale(.large)
.foregroundColor(.accentColor)
Button("Hello, world!") {
showSheet = true
}
}
.padding()
}
.sheet(isPresented: $showSheet) {
ScrollView {
VStack {
Image(systemName: "globe")
.imageScale(.large)
.foregroundColor(.accentColor)
Text("Hello, world!")
}
.padding()
}
.presentationDetents([.medium, .large])
}
.refreshable {
}
}
}
英文:
If I make a parent ScrollView refreshable any other nested ScrollView also will pickup the same refreshable action. Is there a way to prevent this behavior? Here is an example.
struct ContentView: View {
@State var showSheet = false
var body: some View {
ScrollView {
VStack {
Image(systemName: "globe")
.imageScale(.large)
.foregroundColor(.accentColor)
Button("Hello, world!") {
showSheet = true
}
}
.padding()
}
.sheet(isPresented: $showSheet) {
ScrollView {
VStack {
Image(systemName: "globe")
.imageScale(.large)
.foregroundColor(.accentColor)
Text("Hello, world!")
}
.padding()
}
.presentationDetents([.medium, .large])
}
.refreshable {
}
}
}
答案1
得分: 1
将refreshable
修饰符移动到sheet
修饰符之前:
.refreshable {
print("刷新")
}
.sheet(isPresented: $showSheet) {
ScrollView {
...
}
.presentationDetents([.medium, .large])
}
refreshable
只修改其上方的内容,因此不包括sheet
。
英文:
Move the refreshable
modifier to before the sheet
modifier:
.refreshable {
print("Refreshed")
}
.sheet(isPresented: $showSheet) {
ScrollView {
...
}
.presentationDetents([.medium, .large])
}
refreshable
only modifies the things above it, so this excludes the sheet
.
答案2
得分: -2
以下是您要的代码的翻译部分:
这里是一个示例,说明如何在下面的代码中实现不允许嵌套进行刷新操作:
struct ContentView: View {
@State var showSheet = false
@State private var isParentRefreshing = false
var body: some View {
ScrollView {
VStack {
Image(systemName: "globe")
.imageScale(.large)
.foregroundColor(.accentColor)
Button("Hello, world!") {
showSheet = true
}
}
.padding()
.modifier(RefreshableModifier(isRefreshing: $isParentRefreshing))
}
.sheet(isPresented: $showSheet) {
ScrollView {
VStack {
Image(systemName: "globe")
.imageScale(.large)
.foregroundColor(.accentColor)
Text("Hello, world!")
}
.padding()
}
.presentationDetents([.medium, .large])
}
.refreshable {
// 父级滚动视图刷新操作
// 在这里放置您的刷新逻辑
}
}
}
struct RefreshableModifier: ViewModifier {
@Binding var isRefreshing: Bool
func body(content: Content) -> some View {
content
.overlay(
GeometryReader { geometry in
if isRefreshing {
ProgressView()
.offset(y: -geometry.size.height)
.padding(.bottom, -geometry.size.height)
}
}
)
.onPreferenceChange(RefreshablePreferenceKey.self) { isRefreshing = $0 }
.gesture(
DragGesture()
.onChanged { value in
if value.startLocation.y < 50 && value.translation.height > 50 {
isRefreshing = true
}
}
)
}
}
struct RefreshablePreferenceKey: PreferenceKey {
static var defaultValue: Bool = false
static func reduce(value: inout Bool, nextValue: () -> Bool) {
value = nextValue()
}
}
希望这可以帮助您!如果您有任何其他问题,请随时提出。
英文:
Here's an example of how you can achieve not letting the nested have refresh actions in the code below:
struct ContentView: View {
@State var showSheet = false
@State private var isParentRefreshing = false
var body: some View {
ScrollView {
VStack {
Image(systemName: "globe")
.imageScale(.large)
.foregroundColor(.accentColor)
Button("Hello, world!") {
showSheet = true
}
}
.padding()
.modifier(RefreshableModifier(isRefreshing: $isParentRefreshing))
}
.sheet(isPresented: $showSheet) {
ScrollView {
VStack {
Image(systemName: "globe")
.imageScale(.large)
.foregroundColor(.accentColor)
Text("Hello, world!")
}
.padding()
}
.presentationDetents([.medium, .large])
}
.refreshable {
// Parent scroll view refresh action
// Put your refresh logic here
}
}
}
struct RefreshableModifier: ViewModifier {
@Binding var isRefreshing: Bool
func body(content: Content) -> some View {
content
.overlay(
GeometryReader { geometry in
if isRefreshing {
ProgressView()
.offset(y: -geometry.size.height)
.padding(.bottom, -geometry.size.height)
}
}
)
.onPreferenceChange(RefreshablePreferenceKey.self) { isRefreshing = $0 }
.gesture(
DragGesture()
.onChanged { value in
if value.startLocation.y < 50 && value.translation.height > 50 {
isRefreshing = true
}
}
)
}
}
struct RefreshablePreferenceKey: PreferenceKey {
static var defaultValue: Bool = false
static func reduce(value: inout Bool, nextValue: () -> Bool) {
value = nextValue()
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论