SwiftUI NavigationLink how to get to another SwiftUI page? - swiftui

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

Related

SwiftUI ZStack not showing bottom element with List

When put Image to the bottom of ZStack , image just not showing
struct ContentView: View {
var body: some View {
VStack{
ZStack{
Image(systemName:"folder") // not showing
.resizable()
.scaledToFit()
.frame(width: 70, height: 70, alignment: .center)
List {
ForEach(1...8, id: \.self){ i in
Text("ROW \(i)")
}
}
}
}
}
}
and image will show if it's on top.
struct ContentView: View {
var body: some View {
VStack{
ZStack{
List {
ForEach(1...8, id: \.self){ i in
Text("ROW \(i)")
}
}
Image(systemName:"folder") // This will show
.resizable()
.scaledToFit()
.frame(width: 70, height: 70, alignment: .center)
}
}
}
}
How can I show the image at bottom, and hide it when List scroll to the top of image?
You can achieve the result you are looking for by changing the background of the list like this:
struct ContentView: View {
var body: some View {
List {
ForEach(1...8, id: \.self){ i in
Text("ROW \(i)")
}
}
.background(
ZStack {
// Apply the default list background color in case you want it
Color(UIColor.systemGroupedBackground)
.edgesIgnoringSafeArea(.all)
Image(systemName: "folder")
.resizable()
.scaledToFit()
.frame(width: 70, height: 70, alignment: .center)
}
)
.scrollContentBackground(.hidden)
}
}

Utilize HStack to confirm to logo and skip text

Does anyone know how to make the following view in SwiftUI?
HStack:
[ blank logo(centered) Skip(text)]
So I have the following HStack:
Zstack(alignment: .topLeading) {
VStack{
HStack {
Image("onboarding-logo")
.resizable()
.scaledToFit()
.frame(width: 150.0, height: 150.0)
.padding(.top, 35)
}
}
}
Does anyone know how I can have a "Skip" text in the top right corner of the screen, but also keep my logo centered and not have anything on the left side? I've tried Spacers and all, but I'm having no luck.
I would like to click "Skip" and then lead to another view.
There are many ways to achieve this. Here I have used LazyVGrid since other answers based on Stacks
struct ContentView: View {
var body: some View {
VStack {
LazyVGrid(columns: [GridItem(), GridItem(), GridItem()], content: {
Spacer()
Image(systemName: "star.fill")
.frame(width: 150, height: 150, alignment: .center)
.border(.gray)
Button(action: {
}, label: {
Text("Skip")
})
})
.border(.gray)
Spacer()
}
}
}
Is this the screen configuration you want?
The Zstack is used to center the Hstack into which the image is placed, and the new HStack uses a spacer to move the Text to the right.
import SwiftUI
struct ContentView: View {
var body: some View {
ZStack {
VStack {
HStack(alignment: .center) {
Image("farnsworth")
.resizable()
.scaledToFit()
.frame(width: 150.0, height: 150.0)
}
Spacer()
}
VStack {
HStack {
Spacer()
Button {
// do Something...
} label: {
Text("Skip>>")
.padding(.top, 10)
}
}
Spacer()
}
}
.padding()
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}

Why is the button in the body behaving differently than the button in my NavigationView toolbar?

I don't really follow why the following button:
Button { } label: {
Image(systemName: "globe")
.resizable()
.scaledToFill()
}
.frame(width: size, height: size)
.border(.yellow)
is behaving differently in the body and in the NavigationView?
Why isn't the one in the NavigationView filling the entire frame?
struct ContentView: View {
let size = 45.0
let fontSize = 17.0
var body: some View {
NavigationView {
Button { } label: {
Image(systemName: "globe")
.resizable()
.scaledToFill()
}
.frame(width: size, height: size)
.border(.yellow)
.toolbar {
HStack(alignment: .top) {
Button { } label: {
Image(systemName: "globe")
.resizable()
.scaledToFill()
}
.frame(width: size, height: size)
.border(.red)
// Image and Title
VStack {
Image("nemo")
.resizable()
.scaledToFit()
.frame(height: size)
Text("Navigation Title")
.font(.system(size: fontSize))
.bold()
}.border(.green)
}
//.frame(maxWidth: .infinity)
}
}
}
}
This is a design of default button in toolbar, instead we can use custom, like
Button { print(">> action here")} label: {
Image(systemName: "globe")
.resizable()
.scaledToFill()
}
.buttonStyle(MyTabbarButtonStyle())
.frame(width: size, height: size)
.border(.red)
// and style (tune colours as you want)
struct MyTabbarButtonStyle: ButtonStyle {
func makeBody(configuration: Configuration) -> some View {
configuration.label
.foregroundColor(configuration.isPressed ? .gray : .blue)
}
}

Navigation Link leading to gray screen in Swift UI

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

full screen background image with vstack

i want to have a full screen background image with a navigationview (must be on top because it is from the basis view and not in "this" view normally).
In this view i want a VStack which is just inside the secure area, so between navigationbar and bottom layout.
unfortunately i got (see picture)
I expected the texts inside...
struct ContentView: View {
var body: some View {
NavigationView {
ZStack(alignment: .center) {
Image("laguna")
.resizable()
.edgesIgnoringSafeArea(.all)
.scaledToFill()
.frame(width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height)
VStack(alignment: .center) {
Text("just a test")
.font(.largeTitle)
.foregroundColor(Color.white)
Spacer()
Text ("not centered....why?")
.font(.largeTitle)
.foregroundColor(Color.white)
}
.zIndex(4)
.navigationBarTitle("nav bar title")
}
}
}
}
Here is a bit modified variant. Tested with Xcode 11.4 (finally released) / iOS 13.4
struct TestFullScreenImage: View {
var body: some View {
NavigationView {
ZStack {
Image("large_image")
.resizable()
.edgesIgnoringSafeArea(.all)
.scaledToFill()
VStack {
Text("Just a test")
.font(.largeTitle)
.foregroundColor(.white)
Spacer()
Text("centered")
.font(.largeTitle)
.background(Color.green)
}
.navigationBarTitle("Navigation Title")
}
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
}
}
If need to use NavigationView, and maintain the image's aspect ratio, you can do this:
import SwiftUI
struct FullScreenPictureDemo: View {
var body: some View {
NavigationView {
ZStack {
Image("your_full_screen_background_picture")
.resizable()
.aspectRatio(contentMode: .fill)
.edgesIgnoringSafeArea(.all)
.scaledToFill()
}
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
}
}