SwiftUI - ForEach Loop in code is not displaying on tab - swift

In my .tabItem 3 my loop is not displaying in the preview. Am I missing something? Still learning swift...
.tabItem {
VStack {
Image(systemName: "gamecontroller")
Text("Tab 3")
VStack {
List{
ForEach(0..<100) { index in
Text("This is tab 3!")
}
}
}
}
}

Your ForEach is inside the .tabItem, which is the tab bar icon. There's no way that tiny button can display 100 items.
I assume you want the ForEach to be that tab's screen?
Just put the VStack before the .tabItem.
VStack {
List{
ForEach(0..<100) { index in
Text("This is tab 3!")
}
}
}
.tabItem {
VStack {
Image(systemName: "gamecontroller")
Text("Tab 3")
}
}

Related

SwiftUI TabView covers content view

Is it possible to have TabView tabItem to be positioned below the screen content?
My layout is:
var body: some View {
TabView {
self.contentView
.tabItem {
Image(systemName: "chart.bar.fill")
Text("Chart")
}
Text("Screen 2")
.tabItem {
Image(systemName: "person.3.fill")
Text("Leaderboard")
}
Text("Screen 3")
.tabItem {
Image(systemName: "ellipsis")
Text("More")
}
}
}
The actual result looks like this:
Is it possible to position TabView below the content layout, not on top of it? Or the option would be to set bottom padding on content view (and in this case it would be required to check the TabView height).
The contentView layout looks like this:
VStack {
List() { ... }
HStack { Button() Spacer() Button() ... }
}
The contentView contains a List, and it fills all available space, moving buttons that are located below the List under the TabView. Adding Space after the contentView solves the issue.
var body: some View {
TabView {
VStack {
self.contentView
Spacer()
}
.tabItem {
Image(systemName: "chart.bar.fill")
Text("Chart")
}
Text("Screen 2")
.tabItem {
Image(systemName: "person.3.fill")
Text("Leaderboard")
}
Text("Screen 3")
.tabItem {
Image(systemName: "ellipsis")
Text("More")
}
}
}
Thank you #Asperi for pointing in right direction, and checking the children of the contentView.
Just add to your content view:
.padding(.bottom, tabBarHeight)

SwiftUI: Tabview Repeating itself

I'm trying to create a tabview for a macOS 10.15 app.
TabView {
BookmarksView()
.tabItem {
Text("Bookmark Settings")
}
DisplaySettings()
.tabItem {
Text("Display Settings")
}
}
And in any of my views included in the tab that has one element in the body it renders properly in the tab view.
struct BookmarksView: View {
var body: some View {
Text("Bookmarks View")
.font(.title)
.font(Font.body.bold())
}
}
But if i add any other element in the view, the tab repeats and shows the added element in its own tab.
struct BookmarksView: View {
var body: some View {
Text("Bookmarks View")
.font(.title)
.font(Font.body.bold())
Text("Testing")
.font(.system(size: 15))
}
}
Try to wrap them in container (stack or something) explicitly, like
struct BookmarksView: View {
var body: some View {
VStack { // << this !!
Text("Bookmarks View")
.font(.title)
.font(Font.body.bold())
Text("Testing")
.font(.system(size: 15))
}
}
}

SwiftUI TabBar: Action for tapping TabItem of currently selected Tab to reset view

The app I am working on is based around a TabBar, and when I am on a tab I want to be able to click the tabItem again to reset the view, similar to how Twitter does it in their tabBar.
I do not know how to recognize that action though. Adding a button to the TabItem is not working, addidng a tapGesture modifier isn't either, and I can't think of anything else I could try.
struct ContentView: View {
var body: some View {
TabView() {
Text("Tab 1")
.tabItem {
Image(systemName: "star")
.onTapGesture {
print("Hello!")
}
Text("One")
}
.tag(0)
Text("Tab 2")
.tabItem {
Button(action: {
print("Hello!")
}, label: {
Image(systemName: "star.fill")
})
}
.tag(1)
}
}
}
It should't automatically reset when opening the tab again, which I have seen discussed elsewhere, but when tapping the tabItem again.
What other things am I possibly missing here?
Here is possible solution - inject proxy binding around TabView selection state and handle repeated tab tapped before bound value set, like below.
Tested with Xcode 12.1 / iOS 14.1
struct ContentView: View {
#State private var selection = 0
var handler: Binding<Int> { Binding(
get: { self.selection },
set: {
if $0 == self.selection {
print("Reset here!!")
}
self.selection = $0
}
)}
var body: some View {
TabView(selection: handler) {
Text("Tab 1")
.tabItem {
Image(systemName: "star")
Text("One")
}
.tag(0)
Text("Tab 2")
.tabItem {
Image(systemName: "star.fill")
}
.tag(1)
}
}
}

SwiftUI Set Image Boundary

i want to set my right image frame boundaries like the left one without moving image or text. How can I do that. I tried a couple way but I couldn't find the solution.
You should use the built-in TabView. It provides all the functionality for you, and already made with accessibility in mind.
Here is an example (you can change it for your text and images):
struct ContentView: View {
#State private var selection: Int = 1
var body: some View {
TabView(selection: $selection) {
Text("Tab Content 1")
.tabItem {
Label("1", systemImage: "1.square")
}
.tag(1)
Text("Tab Content 2")
.tabItem {
Label("2", systemImage: "2.square")
}
.tag(2)
Text("Tab Content 3")
.tabItem {
Label("3", systemImage: "3.square")
}
.tag(3)
}
}
}
Result:
Custom version (highly unrecommended):
struct ContentView: View {
var body: some View {
VStack {
Spacer()
Text("Main Content")
Spacer()
HStack {
VStack {
Button {
//
} label: {
Label("1", systemImage: "1.square")
}
}.frame(maxWidth: .infinity)
VStack {
Button {
//
} label: {
Label("2", systemImage: "2.square")
}
}.frame(maxWidth: .infinity)
VStack {
Button {
//
} label: {
Label("3", systemImage: "3.square")
}
}.frame(maxWidth: .infinity)
}.frame(height: 50)
}
}
}

NavigationView doesn't display correctly when using TabView in SwiftUI

Hello everyone. I'm developing a simple SwiftUI application that displays some tweets. It has a tab view with two views: the main page that will display the tweets and a secondary view.
The problem is that the main page has a NavigationView. If I choose to display only the main page, everything seems correct, but when I display it from the TabView and I scroll down, the NavigationView feels a bit weird.
As I'm not good at explaining, here you have some images:
It should be like this
But it is like this
I thought of adding .edgesIgnoringSafeArea(.top), but the NavigationView is now hidden by the notch and it doesn't make the effect.
Is there any way I can make the NavigationView display like in the first image?
Any help is appreciated. Thanks in advance.
My code
HomePageView:
struct HomePageView: View {
var body: some View {
NavigationView {
List {
//tweet code
}
.navigationBarTitle("Your feed")
}
}
}
TabView:
struct TabController: View {
#State private var selection = 0
var body: some View {
TabView(selection: $selection){
HomePageView()
.tabItem {
VStack {
Image(systemName: "house.fill")
.font(.title)
}
}
.tag(0)
Text("Second View")
.font(.title)
.tabItem {
VStack {
Image(systemName: "bell.fill")
.font(.title)
}
}
.tag(1)
}
}
}
Try adding .edgesIgnoringSafeArea(.top) to your tabview.
struct ContentView: View {
#State private var selection = 0
var body: some View {
TabView(selection: $selection){
HomePageView()
.tabItem {
VStack {
Image(systemName: "house.fill")
.font(.title)
}
}
.tag(0)
Text("Second View")
.font(.title)
.tabItem {
VStack {
Image(systemName: "bell.fill")
.font(.title)
}
}
.tag(1)
}.edgesIgnoringSafeArea(.top)
}
}