TabView's dots cannot be hidden with an animation - swiftui

I have a TabView with a .page style. I added a button to show / hide the dots with an animation.
When I click the button to display the dots, the animation plays smoothly. However, when I click the button to hide the dots, they disappear instanlty.
The button's text changes if the dots are visible/hidden. Weirdly, both animations are working on the text.
What did I miss? Why is the animation not working as expected?
Here is the code :
import SwiftUI
struct ContentView: View {
#State private var activeTab : Int = 0
#State private var showDots = true
var body: some View {
VStack {
TabView(selection: $activeTab) {
Text("Foo").tag(0)
Text("Bar").tag(1)
}
.tabViewStyle(.page(indexDisplayMode: showDots ? .always : .never))
.indexViewStyle(.page(backgroundDisplayMode: showDots ? .always : .never))
Button(action: {
withAnimation(.linear(duration: 1)) {
showDots.toggle()
}
}) {
Text(showDots ? "Hide dots" : "Show dots")
}
}
.padding()
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
Thanks

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)
}
}
}
}

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.

SwiftUI button to change view

I followed this tuto : https://www.youtube.com/watch?v=mUMR5TCqpDU
Until the end it's ok. But now I would like to add a button.
So I created : bouton1 and 2 at the top
And this is the header of my page : headerview
I would like to go on another view when I click on Bouton2 for example. I guess it's a basic functionality, BUT I when I add navigationview that change everything on my page..
I guess it's because I have a header that should be different..
I tried with
Here my HeaderView.swift
import SwiftUI
struct HeaderView: View {
var body: some View {
NavigationView {
Text("ttt").navigationBarItems(leading:
NavigationLink(destination: GarageView()) {
Text("ey")
},
trailing:
Button(action: {}) {
Text("ee")
}
)
}
.accentColor(.green)
}
}
struct HeaderView_Previews: PreviewProvider {
static var previews: some View {
HeaderView()
.previewLayout(.fixed(width: 375, height: 300)) //375 80
}
}
and my contentView.swift :
import SwiftUI
struct ContentView: View {
var body: some View {
VStack{
// Top Stack
HeaderView()
// Card
ZStack {
ForEach(Card.data.reversed()) { card in
CardView(card: card).padding(10)
}
}.zIndex(1.0)
// Bottom Stack
FooterView()
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
but the result is : I don't know why the header is big like this then i click on the button "ey" -> as you can see the new page is the half of my screen
I would like my new page take the entire screen...
Do you have an idea ?
Thank you.

SwiftUI NavigationView show master on left

I have some master detail in Swift UI. Here it is:
import SwiftUI
struct MenuItemView: View {
var title: String
#Environment(\.presentationMode) var presentationMode
private var btnBack : some View { Button(action: {
//if landscape just show list on the left
//same if swipe from left
//how to do that???
self.presentationMode.wrappedValue.dismiss()
}) {
Text("Menu")
}
}
var body: some View {
Text(title)
.navigationBarTitle(Text(title), displayMode: .inline)
.navigationBarBackButtonHidden(true)
.navigationBarItems(leading: btnBack)
}
}
struct ContentView: View {
#State private var items: [String] = ["Home", "Events", "Topics", "Latest"]
var body: some View {
NavigationView {
List {
ForEach(self.items, id: \.self) { item in
NavigationLink(destination: MenuItemView(title: item)) {
Text(item)
}
}
}
.listStyle(GroupedListStyle())
.navigationBarTitle(Text("TimelessToday"), displayMode: .inline)
Text("Initial")
}
}
}
#if DEBUG
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
#endif
This is working exactly as I plan in portrait mode for any IPhone. But in landscape for IPhone 11 or for IPad in portrait I want "Menu" button when pressed to show left menu with list of items. Same like when doing swipe from left side to show it.
Can't understand how to do this.

SwiftUI - NavigationLink not working when clicked

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
}
}
}
}
}