Why tabView jump one view back in orientation change? - swiftui

I am using down simple code for tabView. when I change the orientation of simulator, the app tab jump one tab back. like this if you are in page 2 goes to 1, but it must stays at page 2 how ever I changed the orientation. or if you are in page 3 jump to page 2. why this unwanted jump happens?
struct ContentView: View {
#State var currentPage: Int = 1
var body: some View {
ZStack
{
Color.gray.ignoresSafeArea()
TabView(selection: $currentPage)
{
Text("Hi 1").tag(0)
Text("Hi 2").tag(1)
Text("Hi 3").tag(2)
}
.indexViewStyle(PageIndexViewStyle(backgroundDisplayMode: .never))
.tabViewStyle(PageTabViewStyle())
}
}
}

Related

NavigationStack and TabView in Swiftui iOS 16: bug or improper usage?

[Xcode 14.1, iOS 16.1]
I have a NavigationStack with a navigationTitle and a TabView with 2 Views. Each View has a ScrollView (see image below):
NavigationStack and TabView problem image
When I tap on Tab1 (#1 in red on the image above), then swipe up, the behavior is as expected (#2), i.e. the big navigationTitle move to the center, and my view passes below and becomes blurry. Perfect.
However, when I tap ton Tab2 (#3) and then swipe up (#4), the big title stays big, and the view doesn't become blurry.
Then I tap on Tab1 again (#5) and it works as expected.
Please help!
Here is my code:
ContentView:
import SwiftUI
struct ContentView: View {
#State private var selection: Tab = .tab1
enum Tab {
case tab1
case tab2
}
#State private var mainTitle = "Tab1"
var body: some View {
NavigationStack {
TabView(selection: $selection) {
Tab1(mainTitle: $mainTitle)
.tabItem {
Label("Tab1", systemImage: "wrench.adjustable.fill")
}
.tag(Tab.tab1)
Tab2(mainTitle: $mainTitle)
.tabItem {
Label("Tab2", systemImage: "wrench.adjustable.fill")
}
.tag(Tab.tab2)
} .navigationTitle(mainTitle)
}
}
}
Tab1:
import SwiftUI
struct Tab1: View {
#Binding var mainTitle : String
var body: some View {
ScrollView {
Text("Text tab 1")
.padding(.all,100)
.background(.blue)
} .onAppear {
mainTitle = "Tab1"
}
}
}
Tab2:
import SwiftUI
struct Tab2: View {
#Binding var mainTitle : String
var body: some View {
ScrollView {
Text("Text tab 2")
.padding(.all,100)
.background(.green)
} .onAppear {
mainTitle = "Tab2"
}
}
}
I tried a hack that is supposed to fix the transparency bug for Tab bars, but it doesn't work.
.onAppear {
let tabBarAppearance = UITabBarAppearance()
tabBarAppearance.configureWithOpaqueBackground()
UITabBar.appearance().scrollEdgeAppearance = tabBarAppearance
}
TabViews are designed to sit at the top of the navigation hierarchy. They're intended to allow users to switch between independent sections of your app at any time.
You would generally put a separate navigation stack within each tab that then handles pushing and popping of views. And then, you can use the navigationTitle modifier to manage the screen's title.
So your structure (which might be split over multiple custom views) should look something like:
TabView {
NavigationStack {
ScrollView {
}
.navigationTitle("Tab 1")
}
.tabItem { Label("Tab1", ...) }
NavigationStack {
ScrollView {
}
.navigationTitle("Tab 2")
}
.tabItem { Label("Tab2", ...) }
}
This structure is by design, to align with Apple's Human Interface Guidelines. It's worth reading the HIG to get a handle on where Apple are coming from, and how working on the same principles can really help your app feel like it belongs on your users' device.

TabView taking Top Space in SwiftUI

Hi I am currently working on swiftUI project. I am facing a very strange issue. Here is the code for my problem. As you can see that, this tabView is taking some space from the Top which is highlighted in Red Color. It should be All blue in the View.
Why it is taking that extra space from the Top?
Kindly Review the code and help me with this problem as i'm a beginner.
import SwiftUI
struct StackOverFlowView: View {
#State private var selection = 0
var body: some View {
ZStack() {
Color.red
TabView(selection: $selection) {
Color.blue
}
.tabViewStyle(PageTabViewStyle())
.edgesIgnoringSafeArea(.all)
}.ignoresSafeArea(.all)
}
}
struct StackPreview: PreviewProvider {
static var previews: some View {
StackOverFlowView()
}
}

Combining Navigation Bar, TabView and searchable causes the NavigationBar UI issue with lists

Combining Navigation Bar, TabView and searchable causes the NavigationBar and Search InputField to stay stationary when scrolling up on the second selected tab.
If I run the code below and first click on the Bookmark tab and scroll the list up, I get the desired results as shown in Figure 1.
If I immediately click the Home tab after the Bookmark tab and scroll the list up, I get an undesirable effect of the list displaying underneath the navigation header as shown in Figure 2.
The order that you click on the tabs produces different effects, and the position you last left the list before going to the next tab also has some strange influence on the behavior.
I need to use the TabView because it "remembers" the position of the list when you move from tab to tab. Creating my own tab control causes the list to reset everytime its displayed and I understand why. We also need to wrap the TabView under the NavigationView because our application subviews need to display their own tabs.
My questions, what am I doing wrong that is causing these inconsistencies in the navigation header. I have tried putting each list in it's own Stack but no joy, same issue keeps happening.
Any assistance would be greatly appreciated, we are currently blocked on our navigation design because of this anomaly. Hoping it's out fault so we can correct it.
----> the complete code <-------------------------------------------------------
struct ContentView: View {
#State var selectedTab: String = "Home"
#State var searchText: String = ""
var body: some View {
NavigationView {
TabView(selection: $selectedTab) {
ListView(itemTitle: "Home List", itemCount: 50)
.tabItem {
Image(systemName: "house.fill")
Text("Home")
}.tag("Home")
ListView(itemTitle: "Bookmark List", itemCount: 20)
.tabItem {
Image(systemName: "bookmark.circle.fill")
Text("Bookmark")
}.tag("Bookmark")
Text("Profile Tab")
.tabItem {
Image(systemName: "person.crop.circle")
Text("Profile")
}.tag("Profile")
}
.navigationTitle(selectedTab)
}
.searchable(text: $searchText)
.onSubmit(of: .search) {
// Do something
}
}
}
struct ListView: View {
var itemTitle: String
var itemCount: Int
var body: some View {
List(){
ForEach(1...itemCount,id: \.self){ i in
NavigationLink(destination: ListViewDetailView("\(itemTitle) \(i)")) {
VStack(alignment: .leading){
Text("\(itemTitle) \(i)").padding()
}
}
}
}
}
}
struct ListViewDetailView: View {
var text:String
init(_ text: String){
self.text = text
}
var body: some View {
Text(text).navigationTitle(Text("\(text) Detail"))
}
}

TabView with "PageTabViewStyle" does not update it's content when #State var changes

I came across a weird Issue in SwiftUI.
I created a simple View that only holds a Button
and a TabView that uses the PageViewStyle. It seems that the TabView does not update it's content
correctly depending on the State of the Variable.
It seems that the content gets updated somehow but the View wont be updated how I would expect
Here is the Code of my View:
struct ContentView: View {
#State var numberOfPages: Int = 0
#State var selectedIndex = 0
var body: some View {
VStack {
Text("Tap Me").onTapGesture(count: 1, perform: {
self.numberOfPages = [2,5,10,15].randomElement()!
self.selectedIndex = 0
})
TabView(selection: $selectedIndex){
ForEach(0..<numberOfPages, id: \.self) { index in
Text("\(index)").background(Color.red)
}
}
.frame(height: 300)
.tabViewStyle(PageTabViewStyle(indexDisplayMode: .automatic))
}.background(Color.blue)
}
}
This is how the result looks after tapping the label several Times.
The Initial State is no 0 Pages. After you tap i would expect that the content of the
TabView changes so all Pages will be scrollable and visible but just the page indicator updates it State for some reason.
TabView expects to have container of pages, but you included only one HStack (with own dynamic content), moreover chaining number of pages you have to reset tab view, so here is a fix.
Tested with Xcode 12 / iOS 14
struct ContentView: View {
#State var numberOfPages: Int = 0
var body: some View {
VStack {
Text("Tap Me").onTapGesture(count: 1, perform: {
self.numberOfPages = [2,5,10,15].randomElement()!
})
if self.numberOfPages != 0 {
TabView {
ForEach(0..<numberOfPages, id: \.self) { index in
Text("\(index)").frame(width: 300).background(Color.red)
}
}
.tabViewStyle(PageTabViewStyle(indexDisplayMode: .automatic))
.frame(height: 300)
.id(numberOfPages) // << here !!
}
}
}
}

SwiftUI Splitview the DetailView not in Navigation?

I try to create a splitview in SwiftUI, and I have 2 issues
1. the Detail-View not showing in the navigation
2. if I go to Detail-View from master view it shows in navigation (Navigation top bar), but when it goes to next page, back button not work
struct MainView: View {
var body: some View {
NavigationView {
ListView()
DetailView()
}
}
}
struct ListView: View {
let menuItems = [MenuItem(name: "Login"),
MenuItem(name: "KS & Token"),
MenuItem(name: "Household & Domain"),
MenuItem(name: "Register")]
var body: some View {
VStack{
List{
ForEach(self.menuItems, id:\.id) { item in
NavigationLink(destination: LoginView(menuItem: item)){
Text(item.name)
}
}
}
Spacer()
}
.navigationBarTitle(Text("User Menu"))
}
}
the issue is:
1. DetailView() not showing Navigation top bar
2. in LoginView, when I go to next page with NavigationLink, the app does not show back button, and also add it by code, not help