SwiftUI NavigationLink destination in TabView will be dismissed after background scene phase - swiftui

In the "Dest" view, after my app going to background mode and coming back to foreground mode, the navigation destination is dismissed automatically. How can I prevent this? Here is my code:
import SwiftUI
struct ContentView: View {
var body: some View {
NavigationView {
TabView {
NavigationLink {Text("Dest")} label: {Text("go to dest")}.tabItem {Text("c1")}
Text("a2").tabItem {Text("c2")}
}
}
}
}

Put the NavigationView inside the TabView:
var body: some View {
TabView {
NavigationView { // here
NavigationLink() {
Text("Dest")
} label: {
Text("go to dest")
}
}
.tabItem {Text("c1")}
Text("a2")
.tabItem {Text("c2")}
}
}

Related

SwiftUI how to align the navigation bar title on center when user taps on a navigation link?

I have a TabView in a struct. I add a NavigationView and a NavigationLink. When the view shows up the navigation bar is centered. When i tap on the navigation link the text is on the leading side. How can i make the navigation bar text align to center after i tap the navigation link in iOS 16 and above? I have searched stackoverflow and nothing seems to work in iOS 16 with this specific implementation i am posting below. Any help appreciated.
import Foundation
import SwiftUI
public struct TabViewTest: View {
#State var selectedTab: Int = 0
public var body: some View {
TabView (selection: $selectedTab) {
NavigationView {
NavigationLink(destination: Text("destination"))
{
FeedView(selectedTab: $selectedTab)
.navigationBarTitle("Feed", displayMode: .inline)
.toolbar {
ToolbarItemGroup {
Image(systemName :"magnifyingglass.circle")
.onTapGesture {
selectedTab = 1
}
}
}
}
}
.tabItem {
Text("Feed")
.foregroundColor(.white)
}
.tag(0)
}
}
struct ProfileView: View {
#Binding var selectedTab: Int
var body: some View {
ZStack {
Color.white.ignoresSafeArea()
VStack {
Text("Nav link test tap anywhere")
.font(.largeTitle)
.foregroundColor(.white)
}
}
}
}

Jumpy toolbar items in NavigationView

I tried to use a custom view as the navigation title inside a NavigationView. Every time when the detail view is popped up, the toolbar items are always resized quickly in a second. I also tested adding a button there as ToolbarItem, the same. Am I misuing something?
struct ContentView: View {
var body: some View {
NavigationView {
NavigationLink {
Text("Detail")
.toolbar {
VStack {
Text("title")
Text("subtitle")
}
}
} label: {
Text("Detail")
}
}
}
}
You're missing Toolbar item inside .toolbar.
.toolbar {
ToolbarItem(placement: .principal) { //You're missing this.
VStack {
Text("title")
Text("subtitle")
}
}
}

Why watchOS picker always shows "ScrollView contentOffset binding has been read" warning?

Bare minimum picker test app for watchOS.
import SwiftUI
#main
struct PickerTestApp: App {
var body: some Scene {
WindowGroup {
NavigationView {
ContentView()
}
}
}
}
ContentView
import SwiftUI
struct ContentView: View {
var body: some View {
VStack{
NavigationLink(destination: DistanceSelectView()) {
Text("Next screen")
}
}
}
}
DistanceSelectView
import SwiftUI
struct DistanceSelectView: View {
#State var Age = 1
var body: some View {
VStack {
Picker(selection: $Age, label: Text("Select your age.[\(Age)]")) {
ForEach(10 ..< 100, id: \.self) { num in
Text("\(num)")
}
}
}
}
}
When run, and "Next screen" NavigationLink is pressed, it always displays the following warning:
"ScrollView contentOffset binding has been read; this will cause grossly inefficient view performance as the ScrollView's content will be updated whenever its contentOffset changes. Read the contentOffset binding in a view that is not parented between the creator of the binding and the ScrollView to avoid this."
What I'm doing wrong here?

SwiftUI: NavigationLink pops out immediately on WatchOS 8.1RC in Tabview

I have discovered a regression in watchOS 8.1RC with NavigationLink triggered from a TabView.
It's immediately dismissed.
It was working in watchOS 8.0 or in Simulator (watchOS 8.0).
Do you know a workaround ?
Thanks
Sample code:
import SwiftUI
#main
struct TestNavigationApp: App {
var body: some Scene {
WindowGroup {
NavigationView {
ContentView()
}
}
}
}
struct ContentView: View {
var body: some View {
List {
NavigationLink(destination: ContentView1()) {
Text("To TabView")
}
}
}
}
struct ContentView1: View {
var body: some View {
TabView {
NavigationView {
NavigationLink(destination: ContentView2()) {
Text("To ContentView2")
}
}
VStack {
Text("Screen2")
}
}
}
}
struct ContentView2: View {
var body: some View {
Text("ContentView2")
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
I'm experiencing the same issue with watchOS 8.1 (and 8.3 beta) while it was working with previous watchOS versions.
We were able to get it working again by moving the NavigationView inside the TabView. This workaround isn't ideal at all but it does seem to work.
#State private var tabSelection = 1
var body: some Scene {
WindowGroup {
TabView(selection: $tabSelection) {
NavigationView {
// List goes here
}
.tag(1)
VStack(alignment: .center, spacing: 12, content: {
// content 2nd tab: we didn't have a list in the 2nd tab
})
.tag(2)
}
}
}
However, there are 2 things impacted with this fix:
I didn't get the navigationBarTitle working, so there won't be a title on top of the screen.
If you click on an item in the list, it will navigate to your page (as expected) but the TabView dots at the bottom of the screen will remain.

How can I Hide TabBar in specific Views, in iOS 15 using SwiftUI

I need my TabBar to disappear if I click on a NavigationLink.
I know you can achieve that in iOS 14 with the following code:
NavigationView{
TabView{
View1().tabItem {
Image(systemName: "house.fill")
Text("Home")
}
}
}
And View1:
struct View1: some View {
var body: some View {
NavigationView{
NavigationLink(destination: Text("New Page without the Tabbar")) {
Text("Link")
}
}
}
}
But somehow this don't works in iOS 15...
Are there any other workarounds?
You could try using only one NavigationView, like in this example:
import SwiftUI
#main
struct TestApp: App {
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
struct ContentView: View {
var body: some View {
NavigationView {
TabView {
View1().tabItem {
Image(systemName: "house.fill")
Text("Home")
}
}
}
}
}
struct View1: View {
var body: some View {
// ---> here no NavigationView
NavigationLink(destination: Text("New Page without the Tabbar")) {
Text("Link")
}
}
}