I am new to SwiftUI and am having a bug where my entire screen turns gray when I use too many Navigation Links.
I cannot find any solutions while researching the bug.
I am running the project on the newest version of Xcode 12.4.
My current setup is to have 2 different swiftUI Views, each containing a Navigation Link to the other.
This is what it looks like
Code:
PageOne.swift
struct PageOne: View {
var body: some View {
NavigationView {
VStack {
Text("This is page 1")
.font(.system(size: 36, weight: .bold))
.padding(.bottom)
NavigationLink(
destination: PageTwo(),
label: {
VStack {
Text("Go to Page 2")
.font(.system(size: 24, weight: .medium))
.foregroundColor(.white)
.frame(width: 200, height: 50, alignment: .center)
.background(Color.blue)
.cornerRadius(12)
}
})
}
}
.navigationBarHidden(true)
.navigationBarBackButtonHidden(true)
}
}
PageTwo.swift
struct PageTwo: View {
var body: some View {
NavigationView {
VStack {
Text("This is page 2")
.font(.system(size: 36, weight: .bold))
.padding(.bottom)
NavigationLink(
destination: PageOne(),
label: {
VStack {
Text("Go to Page 1")
.font(.system(size: 24, weight: .medium))
.foregroundColor(.white)
.frame(width: 200, height: 50, alignment: .center)
.background(Color.blue)
.cornerRadius(12)
}
})
}
}
.navigationBarHidden(true)
.navigationBarBackButtonHidden(true)
}
}
Project file
You should only have one NavigationView in the view hierarchy.
Try creating one NavigationView at the root level:
struct ContentView: View {
var body: some View {
NavigationView {
PageOne()
.navigationBarHidden(true)
.navigationBarBackButtonHidden(true)
}
}
}
and then remove NavigationView from subviews:
struct PageOne: View {
var body: some View {
VStack {
Text("This is page 1")
.font(.system(size: 36, weight: .bold))
.padding(.bottom)
NavigationLink(
destination: PageTwo(),
label: {
VStack {
Text("Go to Page 2")
.font(.system(size: 24, weight: .medium))
.foregroundColor(.white)
.frame(width: 200, height: 50, alignment: .center)
.background(Color.blue)
.cornerRadius(12)
}
})
}
.navigationBarHidden(true)
.navigationBarBackButtonHidden(true)
}
}
struct PageTwo: View {
var body: some View {
VStack {
Text("This is page 2")
.font(.system(size: 36, weight: .bold))
.padding(.bottom)
NavigationLink(
destination: PageOne(),
label: {
VStack {
Text("Go to Page 1")
.font(.system(size: 24, weight: .medium))
.foregroundColor(.white)
.frame(width: 200, height: 50, alignment: .center)
.background(Color.blue)
.cornerRadius(12)
}
})
}
.navigationBarHidden(true)
.navigationBarBackButtonHidden(true)
}
}
Related
As I have constructed a list of country codes and I am able to tap on the list items. Here i want to show the tapped or selected country code inside my textfield which means, when I click on a country code it should show inside the textfield. I am new to swiftUI, it would be great if someone helped me to get this.
enter image description here
state variables given as:
#State private var text = ""
#State private var selection: String!
My textfield code goes here:
HStack {
TextField("Country code", text: $text).padding(.leading)
.frame(width: 385, height: 50)
.border(.gray)
.padding(.leading, 25)
.overlay(
Button(action: {
withAnimation {
showCodes.toggle()
}
}, label: {
Image(systemName: "chevron.down")
.foregroundColor(.gray)
.padding(.leading, 320)
.position(x: 215, y: 25)
})
)
.position(x: 195, y: 40)
.padding(.top, -570)
}
List code goes here :
if showCodes == true {
List (selection: $selection) {
ForEach(datas.users, id: \.dial_code) { user in
HStack{
Text(user.name)
.font(.callout)
.foregroundColor(Color.black)
Spacer()
Text(user.dial_code)
.font(.callout)
.foregroundColor(Color.blue)
}
}
}
.listRowInsets(EdgeInsets())
.frame(maxWidth: 400, maxHeight: .infinity, alignment: .leading)
.padding(.top, -585)
}
You can have it like:
ForEach(datas.users, id: \.dial_code) { user in
HStack {
Text(user.name)
.font(.callout)
.foregroundColor(Color.black)
Spacer()
Text(user.dial_code)
.font(.callout)
.foregroundColor(Color.blue)
}
.onTapGesture { text = user.dial_code }
}
I also suggest extracting the HStack along with it's content in a separate func like:
private func getCountryCodeCell(for user: User) -> some View {
HStack {
Text(user.name)
.font(.callout)
.foregroundColor(Color.black)
Spacer()
Text(user.dial_code)
.font(.callout)
.foregroundColor(Color.blue)
}
}
I'm trying to give a shadow to Button using following code.
VStack{
HStack(){
Text("Menu")
.font(.title3)
.fontWeight(.bold)
Spacer()
Image(systemName: "magnifyingglass")
}.padding(.horizontal)
ScrollView(.horizontal){
HStack(){
ForEach(menuOptions, id: \.self){m in
MenuButtons(title:"\(m)")
}
}.frame(height:50)
}
.padding(.horizontal)
.background(.clear)
}.background(.clear)
And my MenuButton struct:
struct MenuButtons: View {
var title: String
var body: some View {
Button(action:{}, label: {
Text(title)
.font(.system(size: 17))
.frame(width:120, height:35)
.cornerRadius(10)
.foregroundColor(Color("secondaryColor"))
.background(Rectangle().fill(.white).shadow(color:.gray,radius:2).cornerRadius(10))
})
}
}
this would be my output:
Expected output:
In above image you can see that shadow is not proper.
How can I achieve the following?
#Dans code works. But its not so much the .tint as the .background of the button, and the order of applying modifiers.
You used a rectangle, then applied shadow, then used cornerRadius. In this order the cornerRadius "cuts off" the shadow applied before.
If you use RoundedRectangle instead (as Dan did) it works fine.
.background(
RoundedRectangle(cornerRadius: 12)
.fill(.white)
.shadow(color:.gray,radius: 2, y: 1)
)
Or you just change the ordering of the modifiers. First cornerRadius, then shadow.
.background(
Rectangle()
.fill(.white)
.cornerRadius(12)
.shadow(color:.gray,radius: 2, y: 1)
)
I believe adding a .buttonStyle(.borderedProminent) and .tint(.clear) may help achieve your desired look. Something like this;
struct ButtonView: View {
let menuOptions = ["Entradas", "Bebidas", "Plato Fuerte", "Postre"]
var body: some View {
VStack{
HStack(){
Text("Menu")
.font(.title3)
.fontWeight(.bold)
Spacer()
Image(systemName: "magnifyingglass")
}.padding(.horizontal)
ScrollView(.horizontal) {
HStack {
ForEach(menuOptions, id: \.self){ m in
MenuButtons(title:"\(m)")
}
}.frame(height:50)
}
.padding(.horizontal)
//.background(.clear)
}//.background(.clear)
}
}
struct MenuButtons: View {
var title: String
var body: some View {
Button(action:{ }, label: {
Text(title)
.font(.system(size: 17))
.frame(width: 120, height: 35)
.cornerRadius(10)
.foregroundColor(.black)
.background(
RoundedRectangle(cornerRadius: 10, style: .circular)
.fill(.white)
.shadow(color: .gray, radius: 2, x: -1, y: 2)
)
})
.buttonStyle(.borderedProminent)
.tint(.clear)
}
}
Result
Basically, I am working on a project in which there is a navigation process, therefore, I have to implement navigationview with tabview. As app loads, initial screen appear(homeview) normal, but an issue arises as soon I switch between tab option, wide space appears. So can anyone guide me in it? I am adding code with this query.
Even I have tried to add navigationView on individual tabitem and on it wide space issue gets resolve but new issue appear that tabbar doesnot hides on navigationlink even i have implemented "uitabbar.appearance.ishidden = true" on respective view
'''
import SwiftUI
struct TabBarView: View {
#State private var selection = 0
var body: some View {
NavigationView{
TabView(selection: $selection) {
HomeView()
.tabItem {
Image("tab_icon1")
.resizable()
.frame(width: 10, height: 10, alignment: .center)
}
.tag(0)
// Text("Search Tab")
SettingView()
.font(.system(size: 30, weight: .bold, design: .rounded))
.tabItem {
Image("tab_icon2")
.resizable()
.frame(width: 30, height: 30, alignment: .center)
}
.tag(1)
//tab_new
// Text("New Tab")
ActivityListView()
.font(.system(size: 30, weight: .bold, design: .rounded))
.tabItem {
Image("tab_new")
.resizable()
.frame(width: 30, height: 30, alignment: .center)
}
.tag(2)
HomeView()
.font(.system(size: 30, weight: .bold, design: .rounded))
.tabItem {
Image("tab_icon3")
.resizable()
.frame(width: 30, height: 30, alignment: .center)
}
.tag(3)
Text("Profile Tab")
.font(.system(size: 30, weight: .bold, design: .rounded))
.tabItem {
Image("tab_icon4")
.resizable()
.frame(width: 50, height: 50, alignment: .center)
}
.tag(4)
}
.edgesIgnoringSafeArea(.top)
.accentColor(Color("Pink"))
.onAppear() {
UITabBar.appearance().barTintColor = UIColor(named: "DarkGray")
UITabBar.appearance().backgroundColor = UIColor(named: "DarkGray")
}
//
}
}
}
'''
NavigationView {
ScrollView{
.navigationTitle("Home")
.toolbar {
ToolbarItemGroup(placement: .bottomBar) {
VStack{
HStack{
NavigationLink(
destination: Home(),
label: {
Image(systemName: "house")
.resizable()
.frame(width: 25.0, height: 20.0)
.foregroundColor(.blue)
.padding()
})
}
}
I cant use NavigationLink(destination : Text("Go home page"),label:{}
It is menu bar I want to freeze this menu bar when I scroll down or up
Thank you so much
import SwiftUI
struct HomeNav: View {
#State var isActiveHome: Bool = false
var body: some View {
NavigationView {
ScrollView{
Text("Main")
NavigationLink(
destination: Text("Home").navigationTitle("Home"),
isActive: $isActiveHome,
label: {
Image(systemName: "house")
.resizable()
.frame(width: 25.0, height: 20.0)
.foregroundColor(.blue)
.padding()
}).hidden().frame(width: 0, height: 0, alignment: .center)
.navigationTitle("Main")
.toolbar {
ToolbarItemGroup(placement: .bottomBar) {
VStack{
HStack{
Button(action: {
isActiveHome = true
}, label: {
Image(systemName: "house")
.resizable()
.frame(width: 25.0, height: 20.0)
.foregroundColor(.blue)
.padding()
})
}
}
}
}
}
}
}
}
I'm trying to get from one SwiftUI view to another SwiftUI view and I'm using a NavigationLink as per the code below, but I'm getting the error: Cannot invoke initializer for type 'NavigationLink<_, _>' with an argument list of type '(destination: PlaylistTable)'
Below is my code for the button which triggers the link to the next view:
struct MusicButton: View {
var body: some View {
NavigationView {
Button(action: {
NavigationLink(destination: PlaylistTable())
})
{ Image(systemName: "music.note.list")
.resizable()
.foregroundColor(Color.white)
.frame(width: 25, height: 25, alignment: .center)
.aspectRatio(contentMode: .fit)
.font(Font.title.weight(.ultraLight))
}
}
}
}
Don't put NavigationLink inside a Button will solve your problem:
NavigationView {
NavigationLink(destination: PlaylistTable())
{ Image(systemName: "music.note.list")
.resizable()
.foregroundColor(Color.white)
.frame(width: 25, height: 25, alignment: .center)
.aspectRatio(contentMode: .fit)
.font(Font.title.weight(.ultraLight))
}
}
If you want to use the button, then move the navigation link to the background.
struct MusicButton: View {
#State var isActive = false
var body: some View {
NavigationView {
Button(action: {
isActive.toggle()
})
{ Image(systemName: "music.note.list")
.resizable()
.foregroundColor(Color.white)
.frame(width: 25, height: 25, alignment: .center)
.aspectRatio(contentMode: .fit)
.font(Font.title.weight(.ultraLight))
}
}
.background(
NavigationLink(destination: PlaylistTable(), isActive: $isActive) {EmptyView()}
)
}
}