Navigation View and Alert Box in SwiftUI

91 Views Asked by At

I have several cards. I want them to navigate to another view only if the two conditions are satisfied (ifButtonDisabled and ifLevelUnlocked). If not, I want the users to see an alert on the basis of a condition that is not satisfied.

Issue:

  1. Navigation View navigates to an Empty View if conditions are not met which I don't want. Instead, I don't want to navigate to any view if conditions are not met.
  2. I am not able to show two alert boxes based on the condition. How to do it.

Also,is there a better way to achieve the above-mentioned functionality?

                ForEach(Array(indexElementsArray.enumerated()), id: \.0) {index, item in
                    NavigationLink {
                        if coreDataHelper.checkIfButtonDisabled(levelName: "Level\(index + 1)") && coreDataHelper.checkIfLevelUnlocked(levelName: "Level\(index + 1)"){
                            ChapterListView(heading: "Lesson \(index+1) - \(item.level)", index: index)
                        }else{
                            EmptyView()
                        }
                    } label: {
                        IndexCard(lessonNumber: index, heading: item.level, image: item.image, bgColor: item.bgColor)
                    }
                    .simultaneousGesture(
                        TapGesture().onEnded({
                            if !coreDataHelper.checkIfButtonDisabled(levelName: "Level\(index + 1)"){
                                if !coreDataHelper.checkIfLevelUnlocked(levelName: "Level\(index + 1)"){
                                    showAlertToCompletePriorLevels.toggle()
                                }
                            }else{
                                showAlertToDownload.toggle()
                            }
                        })
                    )
                }
1

There are 1 best solutions below

0
hayesk On

Instead of a NavigationLink there you should have a Button and a NavigationLink with an isActive: binding that is set based on your condition. No need for your simultaneousGesture. Then each row can have a button that decides whether or not to show an alert or push a new view.

$State private var shouldNavigate = false
$State private var viewIndex: Int = 0
…

ForEach(Array(indexElementsArray.enumerated()), id: \.0) {index, item in
    Button {
        if coreDataHelper.checkIfButtonDisabled(levelName: "Level\(index + 1)") && coreDataHelper.checkIfLevelUnlocked(levelName: "Level\(index + 1)") {
            viewIndex = index
            shouldNavigate = true
        } else if !coreDataHelper.checkIfButtonDisabled(levelName: "Level\(index + 1)") {
            if !coreDataHelper.checkIfLevelUnlocked(levelName: "Level\(index + 1)") {
                showAlertToCompletePriorLevels.toggle()
            }
        } else {
            showAlertToDownload.toggle()
        }
    } label: {
        IndexCard(lessonNumber: index, heading: item.level, image: item.image, bgColor: item.bgColor)
    }
}

NavigationLink("", isActive: $shouldNavigate) {
    ChapterListView(heading: "Lesson \(viewIndex+1) - \(indexElementsArray[viewIndex].level)", index: viewIndex)
}