3

使用 Swift5.3.2、iOS14.4.2、XCode12.4、

我正在尝试使用 iOS14 的新选项卡视图在 SwiftUI 中创建一个 PageView PageTabViewStyle

页面应该可以在页面之间平滑交换。

只要我不以任何方式采取任何onChange行动,这一切都有效selectedIndex

一旦我这样做了,.onChange(of: selectedIndex) { newidx in ...}那么滑动就会变得迟钝,并且不再可以接受可用性。

但是我的应用程序需要跟踪页面索引,并且需要在任何索引更改时执行代码。

如何在 SwiftUI 的 PageView 中检测滑动操作?

我意识到,一旦我使用任何类型的.onReceive().onChange(of: )与其selectedIndex或任何发布者一起使用的滑动手势,我总是会遇到不再流畅的滑动手势。

如何克服这个问题并获得平滑的滑动和索引信息?

这是我的代码:

struct CustomPageView: View {
    
    @ObservedObject var myPageSelectionService = PageSelectionService()
    @State private var contents = ["a","b","c"]
    @State private var selectedIndex: Int = 0
            
    var body: some View {
            
        TabView(selection: $selectedIndex) {
            ForEach(0..<contents.count, id:\.self) { i in
                Text(contents[i]).tag(i)
            }
        }
        .tabViewStyle(PageTabViewStyle(indexDisplayMode: .automatic))
        .onChange(of: selectedIndex) { newIndex in
            print(newIndex)
        }
    }
}

selectedIndex我还尝试了用myService.selectedIndex替换的 Publisher 方法。但没有变化 - 当滑动和内存超出循环时,应用程序会停止!

class MyService: ObservableObject {
    
    @Published var selectedIndex = 0
}

有什么可做的?

如果好奇,这是整个应用程序:

import SwiftUI

enum MyState {
    case waiting
    case running
}

class AppState: ObservableObject {
    
    @Published var myState: MyState = .running
}

class MyService: ObservableObject {
    
    @Published var someServiceValue = 0
}

struct MainView: View {
    
    @StateObject var appState = AppState()
    @StateObject var myService = MyService()
    
    var body: some View {
        ParentView()
            .environmentObject(appState)
            .environmentObject(myService)
    }
}

struct ParentView: View {
    
    @EnvironmentObject var appState: AppState
    @EnvironmentObject var myService: MyService
        
    var body: some View {
        
        NavigationView {
            
            ZStack {
        
                switch appState.myState {
                case .waiting:
                    Text("Waiting")
                case .running:
                    ChildView()
                }
            }
        }
        .navigationViewStyle(StackNavigationViewStyle())
        .onChange(of: myService.someServiceValue) { newValue in
            if newValue == 4 {
                appState.myState = .waiting
            }
        }
    }
}

struct ChildView: View {
    
    @EnvironmentObject var myService: MyService
    
    @State private var contents = ["img_team_ivo","img_team_beat","img_team_benny","img_team_irfan","img_team_jenny","img_team_lukas","img_team_sabrina","img_team_nici","img_team_pascal","img_team_patrick","img_team_silvan","img_team_stephan","img_team_christoph"]
    @State private var selectedIndex: Int = 0
    
    var body: some View {
        
        ZStack {
            ScrollView {
                ZStack {
                    TabView(selection: $selectedIndex) {
                        ForEach(0..<contents.count, id:\.self) { index in
                            ZStack {
                                Image(contents[index])
                                    .resizable()
                                    .scaledToFit()
                            }
                        }
                    }
                    .tabViewStyle(PageTabViewStyle(indexDisplayMode: .automatic))
                }
            }
        }
        
        .onChange(of: selectedIndex) { newIdx in
            // !!!!!!!!!! app stalls - no more smooth swiping of Pages :(
            myService.someServiceValue = newIdx
        }
    }
}
4

0 回答 0