I am trying to build a tinder-like swipe feature but I have an issue. All the cards get stacked together on the first screen like in the screenshot below:
It is supposed to look like below
Here is my code:
MainView
NavigationView {
VStack () {
ZStack {
ForEach(outingsVM.outings, id: \.dateId) { outing in
CardView(outing: outing)
}
}
}
}
CardView
ZStack {
VStack {
HStack {
Text("\(outing.name), \(outing.age)")
}
.frame(width: 320, alignment: .leading)
HStack (alignment: .center) {
Image(systemName: "figure.walk.circle")
Text("\(outing.place)")
}
.frame(width: 320, alignment: .leading)
HStack {
Image(systemName: "calendar.circle")
Text("\(outing.date) \(outing.time)")
}
.frame(width: 320, alignment: .leading)
HStack {
Image(systemName: "creditcard.circle")
Text("\(outing.payment)")
}
.frame(width: 320, alignment: .leading)
// }
HStack (){
Spacer()
//accept date
Button {
showingModal = true
} label: {
Image(systemName: "checkmark.circle.fill")
.font(.system(size: 50))
.foregroundColor(.green)
}
Spacer()
//reject date
Button {
swipeCard(width: -200)
} label: {
Image(systemName: "xmark.circle.fill")
.font(.system(size: 50))
.foregroundColor(.red)
}
Spacer()
}
.frame(width: 320)
.padding()
}
}
How can I fix this?
You need to add a background to your CardView, e.g.
struct CardView: View {
var body: some View {
VStack {
}
.padding()
.background(RoundedRectangle(cornerRadius: 8).fill(.white))
}
}
Related
I am trying to VStack an Image and a Text inside a NavigationLink.
This is my code:
NavigationLink(destination: ContentView()){
Circle()
.fill(Color.green)
.frame(width: 50, height:50)
.overlay(Image(systemName: "arrow.up"))
Text("Send")
.foregroundColor(Color.white)
}
VStack {
if item.title == "Send"{
NavigationLink(destination: ContentView()) {
VStack {
Circle()
.fill(Color.green)
.frame(width: 50, height:50)
.overlay(Image(systemName: "arrow.up"))
Text("Send")
.foregroundColor(Color.black)
}
}
}}
If I try to VStack inside the NavigationLink then nothing would compile. If I try to VStack everything, then the image and the text would still show next to each other.
I am trying to achieve the right example:
This should work
struct ContentView: View {
var body: some View {
NavigationView {
NavigationLink(destination: Text("new View")) {
ZStack {
Circle()
.fill(Color.green.opacity(0.7))
.frame(width: 70, height: 70)
VStack {
Image(systemName: "square.and.arrow.up")
.renderingMode(.template)
.foregroundColor(.white)
Text("send")
.foregroundColor(.white)
}
}
}
}
}
}
I wasn't able to replicate your issue. The following compiles and displayed as desired.
VStack {
NavigationLink(destination: ContentView()) {
VStack {
Circle()
.fill(Color.green)
.frame(width: 50, height:50)
.overlay(Image(systemName: "arrow.up"))
Text("Send")
.foregroundColor(Color.white)
}
}
}
I'm display how many steps I have taken but don't want it in a list. What should I use instead? Thanks
NavigationView {
List(steps, id: \.id) { step in
VStack(spacing: 15){
Text("\(step.count)")
.font(.custom(customFont, size: 100))
.fontWeight(.semibold)
.multilineTextAlignment(.center)
.opacity(5)
.aspectRatio(contentMode: .fill)
.frame(width: 200, height: 200)
.padding(.bottom, -45)
HStack{
Text("Steps Today")
.font(.custom(customFont, size: 40))
.multilineTextAlignment(.center)
}
.frame(maxWidth: .infinity, alignment: .center)
}
following #aheze and generally speaking it should look something like this:
struct ContentView: View {
var body: some View {
NavigationView {
ScrollView {
LazyVStack {
ForEach(steps, id: \.id) { step in
NavigationLink {
// here comes the destination view, this is only dummy
Text("I walked \(step.count) steps")
} label: {
Text("\(step.count)")
.font(.system(size: 100))
.fontWeight(.semibold)
}
}
}
}
.navigationBarHidden(true)
}
}
}
I'm just learning how to use SwiftUI and seem to be having an issue with the ignoreSafeArea() call on a view.
This is my original View:
But when I add ignoreSafeArea to the View it causes strange whitespace errors:
Here is the code I'm using for the main view.
var body: some View {
VStack {
Image("Banner")
.resizable()
.aspectRatio(contentMode: .fill)
.frame(height: self.show ? 120 : 70, alignment: .bottomLeading)
.blur(radius: self.show ? 0 : 2)
.clipped()
.ignoresSafeArea()
HStack {
VStack(alignment: .leading) {
Text(user.name)
.font(.title)
HStack {
Text(user.screenName)
.font(.subheadline)
.foregroundColor(.secondary)
Spacer()
}
}
Spacer()
UserImage(user: user, show: self.$show)
}
.padding()
if self.show {
Divider()
HStack {
Text(user.userDetailsDescription)
.font(.subheadline.weight(.light))
Spacer()
}.padding(.leading)
}
}
}
You should apply the modifier to the VStack instead, so it doesn't just affect Image("Banner").
Change this:
VStack {
Image("Banner")
/* ... */
.ignoresSafeArea()
/* ... */
}
To this:
VStack {
Image("Banner")
/* ... */
/* ... */
}
.ignoresSafeArea(edges: .top)
Incorrect code
Correct code
Alternatively, you could replace the Image with a placeholder space (Color.clear). Then, put the Image inside .background(). This way, the image's frame won't affect any other spacing.
struct ContentView: View {
let show = true
var body: some View {
VStack {
/// placeholder
Color.clear
.frame(height: self.show ? 120 : 70)
.background(
Image("Banner")
.resizable()
.aspectRatio(contentMode: .fill)
.frame(alignment: .bottomLeading)
.blur(radius: self.show ? 0 : 2)
.ignoresSafeArea() /// ignoresSafeArea inside `.background`
)
HStack {
VStack(alignment: .leading) {
Text("User name")
.font(.title)
HStack {
Text("User screen name")
.font(.subheadline)
.foregroundColor(.secondary)
Spacer()
}
}
Spacer()
Circle()
.fill(Color.green)
.frame(width: 100, height: 100)
.offset(x: 0, y: -50)
}
.padding()
if self.show {
Divider()
HStack {
Text("Description")
.font(.subheadline.weight(.light))
Spacer()
}.padding(.leading)
}
Spacer()
}
}
}
Result:
I'm trying to make the circles fit into the HStack such that the HStack size does not increase.
How can I make the circles fit without specifying a fixed frame?
struct ContentView: View {
var body: some View {
NavigationView {
Form {
HStack {
Circle()
.fill(Color.red)
.aspectRatio(1, contentMode: .fit)
Text("Hello")
}
HStack {
Circle()
.fill(Color.blue)
.aspectRatio(1, contentMode: .fit)
Text("Hello")
}
}
}
}
}
Here is a sample of various containers to chose from. SwiftUI will do all the layout, automatically handle rotations and device resolutions.
struct CirclesView: View {
var body: some View {
VStack(spacing: 0) {
Label("Circles", systemImage: "circle").font(.system(size: 24, weight: .black, design: .rounded)).foregroundColor(.pink)
HStack {
Circle()
.foregroundColor(.yellow)
.frame(width: 32, height: 32)
Text("This is a yellow circle")
Spacer()
}
Circle()
.foregroundColor(.orange)
.shadow(radius: 10)
.frame(width: 75)
Divider()
HStack {
VStack {
Circle().foregroundColor(.blue)
Text("Blue").font(.title3)
HStack {
Circle().foregroundColor(.purple)
Text("Purple").font(.caption)
}
}
.padding()
.background(Color.yellow)
ZStack(alignment: Alignment(horizontal: .center, vertical: .center)) {
Circle().foregroundColor(.green)
Text("Green").foregroundColor(.primary)
}
}
}
}
}
I have next problem with my SwiftUI view: I have "User View" , in this view I have 2 buttons - "Saved" and "My achievement". When user tapped on any button , it will show different views (for example: like TabBar).
It will be switch on same screen , not transition to the other view.
Photo
I can create another views , and put it into my , if it needs.
Hope your understand my quick English.
Thank You for help!
Code:
import SwiftUI
struct MainPage: View {
///State variable for default selected tag
#State var selectedView = 3
///Body-view for the main screen
var body: some View {
TabView(selection: $selectedView) {
//MARK: - First screen (1st view)
VStack {
Text("First View")
}///1st Global VStack
.tabItem {
Label("First Item", systemImage: "1.circle")
}.tag(1)
//MARK: - Scond screen (2nd view)
VStack {
Text("Second View")
}///2nd Global VStack
.tabItem {
Label("Second Item", systemImage: "2.circle")
}
.tag(2)
//MARK: - Profile screen (3rd view)
ZStack(alignment: .top) {
Color.clear
HStack(alignment: .center){
VStack {
HStack() {
HStack() {
Button(action: {}, label: {
Image(systemName: "person")
.resizable()
.scaledToFit()
.frame(width: 35 , height: 35)
.foregroundColor(.gray)
})
.padding(.leading , -30)
.padding(.trailing, 20)
Text("User")
.bold()
.font(.custom("title", size: 24))
.lineLimit(1)
}.padding(.trailing , 110)
.frame(width: 260)
Button(action: {}, label: {
Image(systemName: "gearshape")
.resizable()
.scaledToFit()
.frame(width: 35 , height: 35)
.foregroundColor(.gray)
})
}
HStack(spacing: 30) {
Image(systemName: "")
Button(action: {
}, label: {
Text("Saved")
.foregroundColor(.gray)
.font(.custom("title", size: 17))
.lineLimit(1)
})
Image(systemName: "")
Button(action: {}, label: {
Text("My achievement")
.foregroundColor(.gray)
.font(.custom("title", size: 17))
.lineLimit(1)
})
}.frame(width: 300, height: 30, alignment: .center)
HStack(alignment: .center ,spacing: 10){
VStack(alignment: .leading , spacing: 20) {
}.frame(width: 160, height: 2, alignment: .leading)
.background(Color.blue)
.padding(10)
VStack(alignment: .trailing){
}.frame(width: 100, height: 2, alignment: .trailing)
.background(Color.red)
.padding()
}.frame(width: 420, height: 2, alignment: .center)
.background(Color.gray)
.padding(10)
}
}///Top HStack
.frame(width: 300, height: 70, alignment: .center)
.padding()
}///3rd Global ZStack
.tabItem {
Label("Third item", systemImage: "3.circle")
}.tag(3)
//MARK: - End
}
}
}
You could do it with a segmented picker like this.
struct ExampleView: View
{
#State private var selectedView = 0
private let pickerOptions = ["Saved", "Achievements"]
var body: some View {
VStack {
HStack {
Text("ExampleView")
.font(.title)
.bold()
Spacer()
} //: HStack
.padding()
Divider()
Picker(selection: $selectedView, label: Text("")) {
ForEach(0..<pickerOptions.count) {
Text(self.pickerOptions[$0])
} //: ForEach
} //: Picker
.pickerStyle(SegmentedPickerStyle())
.padding()
if selectedView == 0
{
SavedView()
}
else if selectedView == 1
{
AchievementsView()
}
}
}
}