简体   繁体   English

SwiftUI 中的计时器崩溃屏幕

[英]Timer crashing screens in SwiftUI

I have an app that is using a timer to scroll programmatically between views on the onboarding screen.我有一个应用程序使用计时器以编程方式在入职屏幕上的视图之间滚动。 From the onboarding screen, I can go to login then signup screen (or profile then my account screen).从入职屏幕,我可以进入登录然后注册屏幕(或个人资料然后我的帐户屏幕)。 In both ways, when opening the login screen and clicking on signup, the signup screen appears but then disappears and takes me back to login (The same happens when I try to enter My Account screen from the profile screen).在这两种方式中,当打开登录屏幕并单击注册时,注册屏幕会出现但随后消失并让我重新登录(当我尝试从个人资料屏幕进入我的帐户屏幕时也会发生同样的情况)。 Check please the gif attached.请检查随附的 gif。

I've searched all around the web without finding any similar issue.我搜索了整个网络,没有发现任何类似的问题。

Note: I am using NavigationLink to navigate between screens, and I tried also to use both Timer, and Timer.TimerPublisher leading me to the same result, the screens will crash once the timer fires.注意:我正在使用 NavigationLink 在屏幕之间导航,并且我还尝试同时使用 Timer 和 Timer.TimerPublisher 导致我得到相同的结果,一旦计时器触发,屏幕就会崩溃。

Note: When removing the timer (or the code inside onReceive) everything works fine.注意:删除计时器(或 onReceive 中的代码)时,一切正常。 I also suspect that the issue could be related to menuIndex我也怀疑这个问题可能与menuIndex有关

struct OnboardingView: View {

//MARK: - PROPERTIES

@State var menuIndex = 0
@State var openLogin = false
let timer = Timer.publish(every: 4, on: .main, in: .common).autoconnect()

//MARK: - BODY

var body: some View {
    
    NavigationLink(destination: LoginView(), isActive: $openLogin) {}
    
    VStack (spacing: 22) {
        
        ProfileButton(openProfile: $openLogin)
            .frame(maxWidth: .infinity, alignment: .trailing)
            .padding(.horizontal, 22)
            
            OnboardingMenuItem(text: onboardingMenu[menuIndex].title, image: onboardingMenu[menuIndex].image)
                .frame(height: 80)
                .animation(.easeInOut, value: menuIndex)
                .onReceive(onboardingVM.timer) { input in
                    if menuIndex < onboardingMenu.count - 1 {
                        menuIndex = menuIndex + 1
                    } else {
                        menuIndex = 0
                    }
                }
            ...
        }
    }
}

You can only have one detail NavigationLink , if you want more you have to set isDetailLink(false) , this is why you are seeing the glitch.你只能有一个细节NavigationLink ,如果你想要更多,你必须设置isDetailLink(false) ,这就是你看到故障的原因。

FYI you're timer needs to be in @State or it will start from zero every time that View is init, eg on a state change of the parent View .仅供参考,您的计时器需要在@State中,否则每次 View 初始化时它都会从零开始,例如在父View的状态更改时。 The standard way to fix that is to group the related properties into their own struct, eg解决这个问题的标准方法是将相关属性分组到它们自己的结构中,例如

struct OnboardingViewConfig {
    var menuIndex = 0
    var openLogin = false
    let timer = Timer.publish(every: 4, on: .main, in: .common).autoconnect()

    // mutating func exampleMethod(){} 
}

struct OnboardingView: View {

    @State var config = OnboardingViewConfig()

    ...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM