如何在SwiftUI TabView样式页面中禁用回滚

vlurs2pr  于 2023-02-28  发布在  Swift
关注(0)|答案(1)|浏览(148)

我创建了一个SwiftUI视图,其中包含一个带有样式页的TabView,并且需要禁用返回上一页的功能。
最终的结果应该像TikTok或Instagram卷轴一样,但不可能回去看我以前看到的东西。
我尝试使用DragGesture(),但它在TabView上不起作用。
也许我应该用滚动条来做,如果可能的话拉下来刷新,但是我不知道如何做这种类型的分页。
我的实际代码是:

struct PagesView: View {
    var body: some View {
        GeometryReader { proxy in
            TabView{
                ForEach(0..<10) { el in
                    ZStack{
                        Color(.purple)
                        VStack{
                            Text("Page \(el)")
                        }
                    }
                }.rotationEffect(.init(degrees: -90))
                .ignoresSafeArea(.all, edges: .top)
            }.rotationEffect(.init(degrees: 90))
                .frame(width: proxy.size.height)
                .tabViewStyle(.page(indexDisplayMode: .never))
                .frame(width: proxy.size.width)
        }.ignoresSafeArea(.all, edges: .top)
    }
}
wydwbb8l

wydwbb8l1#

你不能用tabView来做这些,实际上很多SwiftUI组件仍在增长,你不能用它们来做你过去用UIKit中的一些视图做的事情,但是这里有一个解决方案来满足你的需要

var translation: CGFloat = 0
var currentPage = 0
var pageHeight: CGFloat = 0
var stackTopY: CGFloat = 0
var isDragging = false

struct ContentView: View {

@State var colors: [Color] = [.pink, .red, .green]
@State var location = CGPoint(x: 0, y: 0)

var body: some View {
    
    VStack(spacing: 5) {
        ForEach(0..<3) { index in
            GeometryReader { innerProxy in
                Rectangle()
                    .foregroundColor(colors[index])
                    .frame(width: innerProxy.frame(in: .global).size.width, height:innerProxy.frame(in: .global).size.height)
                    .coordinateSpace(name: "list_\(index)")
                    .task {
                        if index == colors.count-1 {
                            DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
                                let height = innerProxy.frame(in: .local).height
                                let remaining = abs(height - innerProxy.frame(in: .global).minY)
                                let total = height * CGFloat(index-1) + remaining
                                pageHeight = height
                                stackTopY = total
                                let stackX = innerProxy.frame(in: .local).width - innerProxy.frame(in: .global).maxX
                                location = CGPoint(x: stackX, y: total)
                            }
                        }
                    }
            }
            .frame(minWidth: UIScreen.main.bounds.width, minHeight: UIScreen.main.bounds.height)
        }
        
    }
    .position(location)
    .gesture(DragGesture()
        .onChanged({ value in
            guard  currentPage < colors.count - 1 else {return }
            if translation < value.translation.height  { return }
            
            isDragging = true
            translation = value.translation.height - translation
            location = CGPoint(x: location.x, y: location.y + translation)
            translation = value.translation.height
        })
            .onEnded({ _ in
                guard isDragging else {return}
                guard  currentPage < colors.count - 1 else {return }
                
                isDragging = false
                currentPage += 1
                translation = 0
                let newY = stackTopY - (CGFloat(currentPage) * pageHeight)
                withAnimation {
                    location = CGPoint(x: location.x, y: newY)
                }
                
            }))
   }



}

创建新应用程序,然后使用此代码替换contentView并对其进行测试。但我强烈建议您使用UIKit collectionView和swiftUI代码来实现此分页功能,并使用UIScrollview委托来启用和禁用特定方向的滚动

相关问题