SwiftUI 2.0 TabView 禁用滑动以更改页面

dae*_*ang 6 xcode tabview swiftui

我有一个使用 swiftUI 2.0 PageTabViewStyle 的 TabView。有什么方法可以禁用滑动以更改页面?

我的第一个选项卡视图中有一个搜索栏,但是如果用户正在键入,我不想提供更改它们的功能,我基本上希望它被锁定在该屏幕上,直到所述功能完成。

这是一个显示差异的 gif,我希望在 gif 全屏时禁用选项卡更改。 https://imgur.com/GrqcGCI

n1m*_*1m1 8

以下内容对我有用

TabView(selection: $selectedTab) {
             // contents   
}
.onAppear {
      UIScrollView.appearance().isScrollEnabled = false
}
Run Code Online (Sandbox Code Playgroud)

  • 如果其中一个选项卡中有滚动视图怎么办?这会破坏滚动的功能。 (5认同)

Asp*_*eri 5

尝试类似以下内容(使用一些存根代码进行测试)。这个想法是在某些条件(在你的情况下开始编辑)发生时阻止选项卡视图拖动手势

@State var isSearching = false

// ... other code

TabView {
    // ... your code here

    Your_View()
       .gesture(isSearching ? DragGesture() : nil)  // blocks TabView gesture !!
}
.tabViewStyle(PageTabViewStyle(indexDisplayMode: .always))
Run Code Online (Sandbox Code Playgroud)


小智 5

我尝试了Asperis的解决方案,但我仍然无法禁用滑动,并且将disabled添加到true不起作用,因为我希望子视图具有交互性。对我有用的解决方案是使用 Majid 的( https://swiftwithmajid.com/2019/12/25/building-pager-view-in-swiftui/)自定义寻呼机视图并添加像 Asperi 的解决方案这样的条件。

Majid 的 PagerView 有条件:

import SwiftUI

struct PagerView<Content: View>: View {
    let pageCount: Int
    @Binding var canDrag: Bool
    @Binding var currentIndex: Int
    let content: Content
    
    
    init(pageCount: Int, canDrag: Binding<Bool>, currentIndex: Binding<Int>, @ViewBuilder content: () -> Content) {
        self.pageCount = pageCount
        self._canDrag = canDrag
        self._currentIndex = currentIndex
        self.content = content()
    }
    
    
    @GestureState private var translation: CGFloat = 0
    
    var body: some View {
        GeometryReader { geometry in
            HStack(spacing: 0) {
                self.content.frame(width: geometry.size.width)
            }
            .frame(width: geometry.size.width, alignment: .leading)
            .offset(x: -CGFloat(self.currentIndex) * geometry.size.width)
            .offset(x: self.translation)
            .animation(.interactiveSpring(), value: currentIndex)
            .animation(.interactiveSpring(), value: translation)
            .gesture(!canDrag ? nil : // <- here
                
                DragGesture()
                    .updating(self.$translation) { value, state, _ in
                        
                        state = value.translation.width
                    }
                    .onEnded { value in
                        let offset = value.translation.width / geometry.size.width
                        let newIndex = (CGFloat(self.currentIndex) - offset).rounded()
                        self.currentIndex = min(max(Int(newIndex), 0), self.pageCount - 1)
                    }
            )
        }
    }
    
}

Run Code Online (Sandbox Code Playgroud)

内容查看:

import SwiftUI

struct ContentView: View {
    
    
    @State private var currentPage = 0
    @State var canDrag: Bool = true
    
    
    var body: some View {
        
        PagerView(pageCount: 3, canDrag: $canDrag, currentIndex: $currentPage) {
            VStack {
                Color.blue
                
                
                Button {
                    canDrag.toggle()
                } label: {
                    Text("Toogle drag")
                }

            }
            
            VStack {
                Color.red
                
                
                Button {
                    canDrag.toggle()
                } label: {
                    Text("Toogle drag")
                }

            }
            
            VStack {
                Color.green
                
                
                Button {
                    canDrag.toggle()
                } label: {
                    Text("Toogle drag")
                }

            }
            
        }
        
    }
    
}
Run Code Online (Sandbox Code Playgroud)

  • 默认情况下,手势在透明视图上不起作用。我通过在添加手势之前添加 ```.contentShape(Rectangle())``` 使您的代码正常工作。请参阅:/sf/ask/4130588661/ (2认同)

Mic*_*bro 5

好吧,我认为通过使用以下步骤可以阻止至少 99% 的滑动手势(如果不是 100%):

  1. 2. 添加.gesture(DragGesture())到每个页面添加.tabViewStyle(.page(indexDisplayMode: .never))
SwiftUI.TabView(selection: $viewModel.selection) {
            ForEach(pages.indices, id: \.self) { index in
                pages[index]
                    .tag(index)
                    .gesture(DragGesture())
            }
        }
        .tabViewStyle(.page(indexDisplayMode: .never))
Run Code Online (Sandbox Code Playgroud)
  1. 添加.highPriorityGesture(DragGesture())到所有剩余视图图像、按钮,仍然可以拖动和滑动页面

您也可以在 1. 使用 highPriorityGesture 但它完全阻止每个页面上的拖动,但我需要它们在某些页面中旋转某些内容