winston
winston

Reputation: 3100

NavigationLink doesn't segue to next screen?

I'm trying to use a Navigation Link to automatically segue to the next screen. While debugging, XCode appears to hit the Navigation Link but it doesn't actually do anything. What am I doing wrong? I can trim out some of the code below if it's easier. I wanted to keep everything just in case one of my libraries were causing an issue (don't see why though since the code does make it to the first NavigationLink line). Any help much appreciated. Thanks!

import SwiftUI
import CloudKit

struct ContentView: View {
    @State private var isPresented = false
    @State private var showLink = false
    
    var body: some View {
        ZStack {
            Color(red: 0.19, green: 0.20, blue: 0.42, opacity: 1.00)
                .edgesIgnoringSafeArea(.all)
            VStack {
                Text("App")
                    .font(Font.custom("LuckiestGuy-Regular", size: 40))
                    .bold()
                    .padding()
                    .foregroundColor(.white)
                Button("Snapchat Login Button") { self.isPresented = true}
                    .font(.system(size: 24))
                    .foregroundColor(.white)
                    .padding(.horizontal)
                    .sheet(isPresented: $isPresented) {
                        LoginCVWrapper()
                }
                .background(Color(red: 0.42, green: 0.81, blue: 0.96))
            }
        }.onAppear(){
            self.isCloudAvailable { (_: Error?) in
                return
            }
        }
    }
    
    // check if user is logged in
    let privateDatabase = CKContainer.default().privateCloudDatabase
    func isCloudAvailable(completion: @escaping (Error?) -> Void) {
            CKContainer.default().accountStatus() { (accountStatus, error) in
                // Check if there are any errors
                guard error == nil else {
                    completion(error)
                    return
                }
                // Check the iCloud account status
                switch accountStatus {
                    case .available:
                        // Check if the user is signed into iCloud account
                        if FileManager.default.ubiquityIdentityToken != nil {
                            // User has signed into iCloud
                            completion(nil)
                            
                            // Now check if user already signed into Snapchat by getting their Name in Cloudkit
                            let pred = NSPredicate(value: true)
                               let sort = NSSortDescriptor(key: "name", ascending: false)
                               let query = CKQuery(recordType: "User", predicate: pred)
                               query.sortDescriptors = [sort]

                               let operation = CKQueryOperation(query: query)
                               operation.desiredKeys = ["name", "isNew"]
                               operation.resultsLimit = 50
                             
                               privateDatabase.perform(query, inZoneWith: nil) { (records, error) in
                                    if let error = error {
                                        print(error)
                                        completion(nil)
                                    } else {
                                        
                                        if let records = records {
                                            for record in records{
                                                let name = record.object(forKey: "name") as? String
                                                let isNew = record.object(forKey: "isNew") as? Int
                                                print(name)
                                                if name != nil {
                                                    // check if it's a new user
                                                    
                                                    if isNew == 1{
                                                        // segue to SetupViewController (storyboard)
                                                        NavigationLink(destination: ConnectionView(), isActive: $showLink) {
                                                            Text("Next").bold().font(.title)
                                                        }.navigationBarTitle("Home")
                                                    } else {
                                                        // segue to main TabViewController (storyboard)
                                                        NavigationLink(destination: ConnectionView()) {
                                                            Text("Next").bold().font(.title)
                                                        }.navigationBarTitle("Home")
                                                    }
                                                } 
                                            }
                                        }
                                }
                            }
                        }
                        else {
                            // User has not signed into iCloud
                            let userInfo: [AnyHashable : Any] = [NSLocalizedDescriptionKey :  NSLocalizedString("Unauthorized", value: "Please sign in to iCloud on this device.", comment: "")]
                            // tell user to sign into iCloud
                        }
                    case .noAccount, .restricted, .couldNotDetermine:
                        // Unable to connect to iCloud
                        let userInfo: [AnyHashable : Any] = [NSLocalizedDescriptionKey :  NSLocalizedString("Unauthorized", value: "Unable to connect to iCloud. Please sign in to iCloud on this device.", comment: "")]
                        // tell user to sign into iCloud
                }
            }
        }
    }

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

Upvotes: 0

Views: 471

Answers (1)

David Pasztor
David Pasztor

Reputation: 54716

There are several issues with your code.

First of all, the NavigationLinks need to be part of the body of your view, otherwise they're not added to the UI. You are creating them inside a separate function, which doesn't even return a View, so the navigation links are never actually added to your UI.

Secondly, you need to nest NavigationLinks inside a NavigationView.

Move the NavigationLinks inside the body of your View:

var body: some View {
    NavigationView {
        ZStack {
            Color(red: 0.19, green: 0.20, blue: 0.42, opacity: 1.00)
                .edgesIgnoringSafeArea(.all)
            VStack {
                Text("App")
                    .font(Font.custom("LuckiestGuy-Regular", size: 40))
                    .bold()
                    .padding()
                    .foregroundColor(.white)
                Button("Snapchat Login Button") { self.isPresented = true}
                    .font(.system(size: 24))
                    .foregroundColor(.white)
                    .padding(.horizontal)
                    .sheet(isPresented: $isPresented) {
//                        LoginCVWrapper()
                }
                .background(Color(red: 0.42, green: 0.81, blue: 0.96))
            }
            // Move this around to match your actual UI requirements
            NavigationLink(destination: ConnectionView(), isActive: $showLink) {
                Text("Next").bold().font(.title)
            }.navigationBarTitle("Home")
        }
    }.onAppear(){
        self.isCloudAvailable { (_: Error?) in
            return
        }
    }
}

And then from your icCloudAvailable function, just toggle the value of showLink, since it is a @State and hence will redraw the body whenever changed.

for record in records{
    let name = record.object(forKey: "name") as? String
    let isNew = record.object(forKey: "isNew") as? Int
    print(name)
    showLink = true
}

Upvotes: 2

Related Questions