I have the following files and I don't know why the navigation bar is not showing.
In the first file I am using NavigationView before ContentView().
File 1:
import SwiftUI
#main
struct TwitterCloneApp: App {
var body: some Scene {
WindowGroup {
NavigationView{
ContentView()
}
}
}
}
In second file I am using MainTabView(), but there is no navigation bar space.
File 2
import SwiftUI
struct ContentView: View {
#State private var showMenu = false
var body: some View {
ZStack(alignment: .topLeading){
MainTabView()
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
Here it is the MainTabView.
File 3:
import SwiftUI
struct MainTabView: View {
#State private var selectedIndex: Int = 0
var body: some View {
TabView(selection: $selectedIndex){
FeedView()
.onTapGesture {
self.selectedIndex = 0
}
.tabItem{
Image(systemName: "house")
}.tag(0)
ExploreView()
.onTapGesture {
self.selectedIndex = 1
}
.tabItem{
Image(systemName: "magnifyingglass")
}.tag(1)
NotificationsView()
.onTapGesture {
self.selectedIndex = 2
}
.tabItem{
Image(systemName: "bell")
}.tag(2)
MessagesView()
.onTapGesture {
self.selectedIndex = 3
}
.tabItem{
Image(systemName: "envelope")
}.tag(3)
}
}
}
struct MainTabView_Previews: PreviewProvider {
static var previews: some View {
MainTabView()
}
}
There is no space for the navigation bar.
There are several things wrong with the code you've posted:
Each sub-view within a TabView should have its own NavigationView.
There shouldn't be a NavigationView at the top level
Each top-level view within a NavigationView should have a .navigationTitle
The tapGesture isn't needed to switch between tabs
so you should end up with
struct TwitterCloneApp: App {
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
and
struct MainTabView: View {
#State private var selectedIndex: Int = 0
var body: some View {
TabView(selection: $selectedIndex){
NavigationView {
FeedView()
.navigationTitle("Feed")
}
.tabItem{
Image(systemName: "house")
}.tag(0)
NavigationView {
ExploreView()
.navigationTitle("Explore")
}
.tabItem{
Image(systemName: "magnifyingglass")
}.tag(1)
NavigationView {
NotificationsView()
.navigationTitle("Notifications")
}
.tabItem{
Image(systemName: "bell")
}.tag(2)
NavigationView {
MessagesView()
.navigationTitle("Messages")
}
.tabItem{
Image(systemName: "envelope")
}.tag(3)
}
}
}
Related
When i am Switching the Tab in Swiftui Every Time new View is showing and my previous View was Vanished.I have Tried Userdefaults also but not working.
import SwiftUI
struct HomeView: View {
#State var selectedTabs = "house"
var body: some View {
ZStack(alignment: .bottom) {
Color("LightTabColor")
.edgesIgnoringSafeArea(.all)
VStack{
CardView(selectedTab: selectedTabs)
CustomTabBar(selectedTab: $selectedTabs)
.padding(.bottom)
}
}.onAppear {
let selectedTab = UserDefaults.standard.string(forKey: "selectedTabs")
if let selectedTab = selectedTab {
self.selectedTabs = selectedTab
}
}.onDisappear {
UserDefaults.standard.set(self.selectedTabs, forKey: "selectedTabs")
}
}
}
struct CardView: View {
var selectedTab: String
var body: some View {
ZStack{
Color("LightTabColor")
.cornerRadius(25)
.frame(maxWidth: .infinity,maxHeight: .infinity)
.padding(10)
.shadow(radius: 30)
VStack {
// Show the appropriate view based on the selected tab
switch selectedTab {
case "gear.circle":
NewAI()
case "house":
ImageAI()
case "message":
ChatAI()
default:
ImageAI()
}
Spacer()
}
.padding(.leading,10)
.padding(.bottom,10)
}
}
}
struct HomeView_Previews: PreviewProvider {
static var previews: some View {
HomeView()
}
}
When starting my app on iPadOS, there is a blank view/screen on the right side, so I need a solution to force the app to choose or to lunch with the firstDetailsView().
If there is no solution for this problem, how can I add a Text() View on the right side which tells the user something like that -> no DetailView is selected
Here is the sourcecode
ContentView.swift
import SwiftUI
struct ContentView: View {
var body: some View {
TabView {
HomeView()
.tabItem {
Image(systemName: "house.fill")
Text("Home")
}
SettingsView()
.tabItem {
Image(systemName: "gear.circle")
Text("Settings")
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
SettingsView.swift
import SwiftUI
struct SettingsView: View {
var body: some View {
Text("Settings")
}
}
struct SettingsView_Previews: PreviewProvider {
static var previews: some View {
SettingsView()
}
}
HomeView.swift
import SwiftUI
struct HomeView: View {
var body: some View {
NavigationView {
ScrollView {
VStack (spacing: -15) {
NavigationLink(destination: firstDetailsView()) {
card(symbol: "1.square", color: Color.orange)
}
NavigationLink(destination: secondDetailsView()) {
card(symbol: "2.square", color: Color.green)
}
NavigationLink(destination: thirdDetailsView()) {
card(symbol: "3.square", color: Color.purple)
}
}
}
.navigationTitle("Title")
}
}
}
struct card: View {
var symbol: String
var color: Color
var body: some View {
HStack {
Text("Link to DetailView")
Image(systemName: symbol)
}
.frame(maxWidth: .infinity, minHeight: 100)
.bold()
.foregroundColor(Color.white)
.background(color)
.padding()
}
}
struct HomeView_Previews: PreviewProvider {
static var previews: some View {
HomeView()
}
}
firstDetailsView.swift
import SwiftUI
struct firstDetailsView: View {
var body: some View {
ZStack {
Color.orange
.ignoresSafeArea()
Text("firstDetailsView!")
}
}
}
struct firstDetailsView_Previews: PreviewProvider {
static var previews: some View {
firstDetailsView()
}
}
secondDetailsView.swift
struct secondDetailsView: View {
var body: some View {
ZStack {
Color.green
.ignoresSafeArea()
Text("secondDetailsView!")
}
}
}
struct secondDetailsView_Previews: PreviewProvider {
static var previews: some View {
secondDetailsView()
}
}
I am attempting to implement a PageTabViewStyle inside a NavigationView so that I can swipe between two different lists but the TabView does not ignore the safe area despite having .ignoresSafeArea().
Code
struct TestView: View {
#State private var selectedPage = 0
private var pages = [0, 1]
var body: some View {
NavigationView {
TabView(selection: $selectedPage) {
FirstList()
.ignoresSafeArea()
.tag(0)
SecondList()
.tag(1)
}
.ignoresSafeArea()
.tabViewStyle(PageTabViewStyle(indexDisplayMode: .never))
.navigationBarTitleDisplayMode(.inline)
.toolbar {
ToolbarItem(placement: .principal) {
Picker("", selection: $selectedPage) {
ForEach(pages, id: \.self) {
Text(String($0))
}
}
.scaledToFit()
.pickerStyle(.segmented)
}
}
}
}
}
struct FirstList: View {
var body: some View {
List {
Text("0")
}
}
}
struct SecondList: View {
var body: some View {
List {
Text("1")
}
}
}
Results:
How do I set it such that the list view would fill the navigationBar like the image below:
Note that adding a background color is not preferred as I would like to maintain the navigationBar tint effect when the list view is scrolled.
It is because List has its own background. You can either set listStyle to .plain or manually set the color of List background e.g. onAppear.
struct ContentView: View {
#State private var selectedPage = 0
private var pages = [0, 1]
var body: some View {
NavigationView {
TabView(selection: $selectedPage) {
FirstList()
.ignoresSafeArea()
.tag(0)
SecondList()
.tag(1)
}
.ignoresSafeArea()
.tabViewStyle(PageTabViewStyle(indexDisplayMode: .never))
.navigationBarTitleDisplayMode(.inline)
.onAppear {
// UITableView.appearance().backgroundColor = UIColor(Color.clear) // solution2
}
.toolbar {
ToolbarItem(placement: .principal) {
Picker("", selection: $selectedPage) {
ForEach(pages, id: \.self) {
Text(String($0))
}
}
.scaledToFit()
.pickerStyle(.segmented)
}
}
}
}
}
struct FirstList: View {
var body: some View {
List {
Text("0")
}
.listStyle(.plain) //solution1
}
}
struct SecondList: View {
var body: some View {
List {
Text("1")
}
.listStyle(.plain) //solution1
}
}
I created a TabView with 4 items but with iOS 13.x only the first view is displayed correctly.
When I click on another item's icon, the view is not shown correctly but the app only shows a white view. If I run the app on iOS > 14 I can correctly view all the views.
TabView implementation:
struct ContentView: View {
private enum Tab: Hashable {
case discovery
case qrcode
case devices
case settings
}
#State private var selectedTab: Tab = .discovery
var body: some View {
NavigationView {
TabView(selection: $selectedTab) {
DiscoveryView()
.tabItem {
VStack {
Image(systemName: "lock.rotation.open")
Text("Discovery")
}
}
.tag(0)
QrCodeView()
.tabItem {
VStack {
Image(systemName: "qrcode.viewfinder")
Text("QrCode")
}
}
.tag(1)
DevicesView()
.tabItem {
VStack {
Image(systemName: "qrcode.viewfinder")
Text("My devices")
}
}
.tag(2)
SettingsView()
.tabItem {
VStack {
Image(systemName: "gear")
Text("Settings")
}
}
.tag(3)
}
}
}
Implementation of one of the views:
struct QrCodeView: View {
var body: some View {
Text("QrCode")
}
}
Where am I doing wrong?
It might be a reason of selection... selection and tag types should be the same, so try
#State private var selectedTab: Tab = .discovery
var body: some View {
NavigationView {
TabView(selection: $selectedTab) {
DiscoveryView()
.tabItem {
VStack {
Image(systemName: "lock.rotation.open")
Text("Discovery")
}
}
.tag(.discovery) // << here !!
QrCodeView()
.tabItem {
VStack {
Image(systemName: "qrcode.viewfinder")
Text("QrCode")
}
}
.tag(.qrcode) // << here !!
// ... others the same
I am trying to create a tabbed application in Swift using Swift UI. I am using #ObservedObject to store the current view name that should be rendered.
I am trying to change the background color of the UI Tab Bar however every time I add the init to override the method begins chucking errors such as "Argument passed to call that takes no arguments".
I have attached a snippet of the controller code below. Any help to resolve this issue is much appreciated.
import SwiftUI
struct ContentView: View {
#State private var selection = 0
#ObservedObject var coreRouter: CoreRouter
init() {
UITabBar.appearance().backgroundColor = UIColor.blue
}
var body: some View {
TabView(selection: $selection){
Text("First Screen")
.font(.title)
.tabItem {
VStack {
Image(systemName: "house")
Text("Home")
}
}
.tag(0)
Text("Second View")
.font(.title)
.tabItem {
VStack {
Image("calendar")
Text("New Items")
}
}
.tag(1)
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView(coreRouter: CoreRouter())
}
}
Since your ContentView has a coreRouter property, your init needs to accept a value to assign to that property;
struct ContentView: View {
#State private var selection = 0
#ObservedObject var coreRouter: CoreRouter
init(coreRouter: CoreRouter) {
self.coreRouter = coreRouter
UITabBar.appearance().backgroundColor = UIColor.blue
}
}
try this:
(i had to create a dummy class, because you did not provide the code for corerouter)
class CoreRouter : ObservableObject {
#Published var a = false
}
struct ContentView: View {
#State private var selection = 0
#ObservedObject var coreRouter: CoreRouter
init() {
coreRouter = CoreRouter()
UITabBar.appearance().backgroundColor = UIColor.blue
}
var body: some View {
TabView(selection: $selection){
Text("First Screen")
.font(.title)
.tabItem {
VStack {
Image(systemName: "house")
Text("Home")
}
}
.tag(0)
Text("Second View")
.font(.title)
.tabItem {
VStack {
Image("calendar")
Text("New Items")
}
}
.tag(1)
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}