SwiftUI Open view deep in NavigationView from push notification - ios

I want to open a view after taping on a push notification. The views and notifications are all working fine but my problem is when I try to open the view from the push notification via .sheet(isPresented) it is always presenting the view as modal.
I would like to achieve that the view is actually opened embedded in the NavigationView it would usually be when accessing it manually.
To make it more clear:
import SwiftUI
struct ContentView: View {
var body: some View {
NavigationView{
VStack{
NavigationLink(destination: ListView()){
Text("Going one level down")
}
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
struct ListView: View {
var body: some View{
NavigationLink(destination: DetailView()){
Text("Click me")
}
}
}
struct DetailView: View {
var body: some View{
Text("I want to display this view after tapping on a notification.")
}
}
After tapping on the push notification, I want to jump directly to the DetailView() down in the NavigationView tree (similar to what the Apple Calendar app is doing when you tap on the notification).
Any ideas?

Related

SwiftUI NavigationView list not dismissing itself when NavigationLink is clicked on iPads running iOS 15 in portrait orientation

Since iOS 15, clicking a NavigationLink in a NavigationView sometimes does not dismiss its nested list / sidebar on iPads in portrait orientation. The first click will dismiss the list, then it gets stuck. You can drag / scroll the list up and down to make the auto-hide behavior work again temporarily but it gets stuck again.
Here is some sample code to demonstrate:
import SwiftUI
struct ContentView: View {
var body: some View {
NavigationView {
List {
ForEach(0...30, id: \.self) { n in
NavigationLink(
"\(n)",
destination: DetailView(n: n)
)
}
}
.navigationBarTitle("List")
}
}
}
struct DetailView: View {
var n: Int
var body: some View {
Text("\(n)")
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
Considering how basic the code above is, my guess is that it's an iOS 15 bug but I would appreciate any pointers if it isn't. Thanks!

Change Status Bar Color SwiftUI no UIHosting

I'm trying to change my status bar color dynamically without success, anyone has any idea how to change it ?
I'm not using UIHosting controller so there is no AppDelegate or SceneDelegate fully using swiftUI:
#main
struct MyProjectApp: App{}
If i set ZStack {}.preferredColorScheme(.light) it only apply once, so if i go to another view and try to put ZStack {}.preferredColorScheme(.dark) it doesn't work.
I think i have try all the question here on stackoverflow, so if anyone have a definitive solution i appreciated.
#Updated code example
struct ContentA: View {
var body: some View {
NavigationView {
ZStack {
NavigationLink(destination: ContentB()) {
Text("Show Detail View")
}.navigationBarTitle("Navigation")
}.preferredColorScheme(.light)
}
}
}
struct ContentB: View {
var body: some View {
ZStack {
Text("Hello ContetB")
.padding()
.foregroundColor(.green)
}.preferredColorScheme(.dark)
}
}
If you try to change StatusBar color using this way it doesn't work.
The colors within the app should be dynamic automatically, unless you set them specifically. You can toggle the .preferredColorScheme within the Previews section.
struct ContentView: View {
var body: some View {
Text("Hello, world!")
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
.preferredColorScheme(.dark)
}
}

SwiftUI: Go to a new view from inside a modal

I would like to go to a new view from inside my modal.
Currently I have my default view. I then present my modal. In that modal I can close it but I also have a another button that I would like to take me to another view. (NewView)
IS this possible?
Default view:
import SwiftUI
struct ContentView: View {
#State private var showModal = false
var body: some View {
Button("Show Modal") {
self.showModal.toggle()
}.sheet(isPresented: $showModal) {
ModalView(showModal: self.$showModal)
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
Modal View:
struct ModalView: View {
#Binding var showModal: Bool
var body: some View {
VStack (spacing: 30){
Text("My Modal View")
.font(.title)
.padding()
Button("Close modal") {
self.showModal.toggle()
}
Button("Close modal and go to a new view") {
}
}
}
}
NewView:
struct NewView: View {
var body: some View {
Text("My New View")
}
}
I understood your question in 2 different ways, and luckily I have both solutions.
If you want the following flow: ViewA -> Opens ViewB As modal -> opens ViewC as NavigatedView in ViewB
Then all you need to change is your ModalView to this
struct ModalView: View {
#Binding var showModal: Bool
var body: some View {
NavigationView {
VStack (spacing: 30){
NavigationLink(destination: NewView()) {
Text("Take me to NewView")
}
Text("My Modal View")
.font(.title)
.padding()
Button("Close modal") {
self.showModal.toggle()
}
Button("Close modal and go to a new view") {
}
}
}
}
}
IF however what you mean is ViewA -> opens ViewsB as Moda -> ViewB then tells ViewA to navigate to ViewC
then please refer to this link, someone asked this question earlier and I provided the solution
SwiftUI transition from modal sheet to regular view with Navigation Link

Disable split view using Swift UI on iPad

Is there a way to disable the SplitView using SwiftUI on iPad inside a navigation view?
By setting the NavigationViewStyle
import SwiftUI
struct NavView: View {
var body: some View {
NavigationView{
List{
NavigationLink(destination: TestView(), label: {Text("TestView")})
}
}.navigationViewStyle(StackNavigationViewStyle())
}
}
struct NavView_Previews: PreviewProvider {
static var previews: some View {
NavView()
}
}

NavigationView and NavigationLink not deleting views after transition

I am writing an app using SwiftUI, and I am having some issues with the NavigationView and the Navigation Link, as shown below in the simulator video. The project was created as a Single View App.
I have three pages, and as you can see when it takes me from one page to the other, it builds the second page under the first one, and doesn’t dellocate the first one, and I have the same problem on the third page: it is created below the second one, and I can even go back to the first page via the faulty back button on the top left.
Video:
This is the code of the three pages:
first.swift
import SwiftUI
struct first: View {
var body: some View {
NavigationView{
NavigationLink(destination: second()) {
Text("first link")
}
}
}
}
struct first_Previews: PreviewProvider {
static var previews: some View {
first()
}
}
second.swift
import SwiftUI
struct second: View {
var body: some View {
NavigationView {
NavigationLink(destination: third()) {
Text("second link")
}
}
}
}
struct second_Previews: PreviewProvider {
static var previews: some View {
second()
}
}
third.swift
import SwiftUI
struct third: View {
var body: some View {
Text("Third page")
}
}
struct third_Previews: PreviewProvider {
static var previews: some View {
third()
}
}
I am using the Navigation View in the same manner that the official apple tutorial does (or at least I think I am…) here
Thanks!
Edit: I'm still having the same problem with this code, despite having defined only one NavigationView. The problem came back after I uploaded to Xcode 11.2, but in the Release Notes it doesn't say anything about any changes made to the NavigationView.
first.swift
import SwiftUI
struct first: View {
var body: some View {
NavigationView {
NavigationLink(destination: second()) {
Text("First link")
}
}
}
}
struct first_Previews: PreviewProvider {
static var previews: some View {
first()
}
}
second.swift
import SwiftUI
struct second: View {
var body: some View {
NavigationLink(destination: first()) {
Text("back to first")
}
}
}
struct second_Previews: PreviewProvider {
static var previews: some View {
second()
}
}
Video:
Thanks again!
What your current code is doing is nesting the NavigationView in second inside of the one in first.
To get around this you just need to delete the NavigationView in second:
struct second: View {
var body: some View {
NavigationLink(destination: third()) {
Text("second link")
}
}
}

Resources