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.
Related
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")}
}
}
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?
The code below worked fine in WatchOS 7 and 8.0, but now in 8.1 tapping on the row will navigate to the destination but then immediately navigates back to the root view.
I filed Feedback #FB9727188 and included the below to demonstrate the issue.
struct ContentView: View {
#State var tabIndex:Int = 0
var body: some View {
TabView(selection: $tabIndex) {
ListView()
.tabItem { Group{
Text("List")
}}.tag(0)
.padding(.bottom, 1.0)
Text("Second View")
.tabItem { Group{
Text("Second")
}}.tag(1)
.padding(.bottom, 1.0)
Text("Third View")
.tabItem { Group{
Text("ThirdView")
}}.tag(2)
}
}
}
struct ListView: View {
var body: some View {
List {
ForEach((1...10).reversed(), id: \.self) {_ in
NavigationLink(destination: Text("test")) {
Text("Tap Me but we'll just be back here")
}
}
}
}
}
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 {
// 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.
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")
}
}
}
Currently using:
Xcode 11 Beta 5
Mac OSX Catalina Beta 5
Here is the code:
import SwiftUI
struct SwiftUIView : View {
var body: some View {
NavigationView {
NavigationLink(destination: Product()) {
Text("Click")
}
.navigationBarTitle(Text("Navigation"))
}
}
}
#if DEBUG
struct SwiftUIView_Previews: PreviewProvider {
static var previews: some View {
SwiftUIView()
}
}
#endif
And here is result:
When tapped or clicked on button, it should go to detail view, bit nothing is happening.
Notes:
The Landmark example project by apple, is also not working when tapped on the landmarks on home screen.
This website mentions that "Not sure if it is a bug or by design, in Beta 5 above code won't work"
https://fuckingswiftui.com/#navigationlink
It must be a bug. But as a workaround, when on the top view of a NavigationView, embed NavigationLink inside a VStack. The button will gain its proper style and "clickability".
struct SwiftUIView : View {
var body: some View {
NavigationView {
VStack {
NavigationLink(destination: Product()) {
Text("Click")
}
}.navigationBarTitle(Text("Navigation"))
}
}
}
Works in Xcode(11.2)
struct MasterView: View {
#State var selection: Int? = nil
var body: some View {
NavigationView {
VStack {
NavigationLink(destination: DetailsView(), tag: 1, selection: $selection) {
Button("Press") {
self.selection = 1
}
}
}
}
}