Reputation: 3100
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
Reputation: 54716
There are several issues with your code.
First of all, the NavigationLink
s 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 NavigationLink
s inside a NavigationView
.
Move the NavigationLink
s 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