I am trying to get my controls in a. nice boarded box but I can't seem to fit them it could be my circle size in my progressive but could be just my understanding of my stacks, I am just new to swift ui after using .net C sharp for many years.
This is my main view
import SwiftUI
struct CaloriesView: View {
var body: some View {
ZStack {
ProgressRingView()
}
ZStack{
Label("Base Goals", systemImage: "folder.circle").font(.system(size: 30))
}
HStack{
Label("Daily Limit", systemImage: "flag.fill").font(.system(size: 30))
Label("Food", systemImage: "fork.knife").font(.system(size: 30))
}
HStack{
Label("Exercise Taken", systemImage: "flag.fill").font(.system(size: 30))
}
}
}
struct CaloriesView_Previews: PreviewProvider {
static var previews: some View {
CaloriesView()
}
}
But what am looking moreis the progress ring to the left and the icons properly aligned to the right
This is my circle how I create it in my progress view
Import SwiftUI
struct ProgressRingView: View {
@State var progress = 0.0
let colors: [Color] = [.yellow, .red,.blue, .purple]
var body: some View {
ZStack{
// MARK:Place Holder Ring
Circle()
.stroke(lineWidth: 20)
.foregroundColor(.gray)
.opacity(0.1)
// MARK: Colored Ring
Circle()
.trim(from: 0.0, to: min(progress,1.0))
.stroke( AngularGradient(gradient: Gradient(colors: colors), center: .center,startAngle: .degrees(0), endAngle: .degrees(360 45)) ,style: StrokeStyle(lineWidth: 15, lineCap: .round, lineJoin: .round))
.rotationEffect((Angle(degrees: 270)))
.animation(.easeInOut(duration: 1.0),value:progress)
.onAppear{
progress=1
}
VStack(spacing:30)
{
//MARK : Elapsed Time
VStack(spacing:5)
{
Text("Calories")
.opacity(0.7)
}
.padding(.top)
//MARK :Remiaing Time
VStack(spacing:5)
{
Text("Rmaining ")
.opacity(0.7)
Text("0:00")
.font(.title2)
.fontWeight(.bold)
}
}
}
.frame(width: 250, height: 250)
.padding()
}
}
struct ProgressRingView_Previews: PreviewProvider {
static var previews: some View {
ProgressRingView()
}
}
Edit
To show the style of what am looking for its kinda like my fitness pal but not exactly the same.
CodePudding user response:
Use a combination of HStack and a nested VStack to achieve a similar layout:
struct CaloriesView: View {
var body: some View {
HStack {
ProgressRingView()
VStack(alignment: .leading) {
Label("Base Goals", systemImage: "folder.circle")
Label("Daily Limit", systemImage: "flag.fill")
Label("Food", systemImage: "fork.knife")
Label("Exercise Taken", systemImage: "flag.fill")
}
}
.padding()
}
}
This is how the result looks like on an iPhone 13 simulator:
To make it look nicer, I also took the liberty of fixing a typo, removing a fixed font size of 30 from the labels and shrinking the frame of the ProgressRingView
down to 150x150.
Note that in your original code you're using ZStacks and HStacks with just a single view inside them: that doesn't make much sense because the stack are supposed to lay out several items and they aren't useful for just a single item.
Now, on my screenshot you may notice that the texts of the labels aren't quite aligned, but I'd suggest to do it as a separate exercise because we're all here to learn. Happy SwiftUIing!
CodePudding user response:
I created a little playground app on the iPad to show how you might approach creating this view.
It's not perfect but hopefully will give you some pointers.
I've extracted a couple of the views into reusable components for you and added the title etc...
import SwiftUI
struct ContentView: View {
var body: some View {
VStack(alignment: .center) {
VStack(alignment: .leading) {
Text("Calories")
.font(.system(.largeTitle))
Text("Remaining = Goal - Food Exercise")
}
DataView()
}
.padding()
.background(Color.init(white: 0.05))
.cornerRadius(16)
.shadow(color: .black, radius: 5, x: 0, y: 0)
}
}
struct DataView: View {
var body: some View {
HStack(spacing: 50) {
CircleView()
VStack(alignment: .leading) {
TagView(
image: .init(systemName: "flag.fill"),
color: .gray,
title: "Base Goal",
number: 2300
)
TagView(
image: .init(systemName: "fork.knife"),
color: .blue,
title: "Food",
number: 0
)
TagView(
image: .init(systemName: "flame.fill"),
color: .orange,
title: "Exercise",
number: 0
)
}
}
}
}
struct TagView: View {
let image: Image
let color: Color
let title: String
let number: Int
var body: some View {
HStack {
image
.resizable()
.aspectRatio(contentMode: .fit)
.foregroundColor(color)
.frame(width: 20, height: 30, alignment: .center)
VStack(alignment: .leading) {
Text(title)
.font(.system(.subheadline))
Text("\(number)")
.font(.system(.headline))
}
}
}
}
struct CircleView: View {
var body: some View {
ZStack {
Circle()
.stroke(
AngularGradient(colors: [.red, .green, .blue, .red], center: .init(x: 0.5, y: 0.5)),
lineWidth: 5
)
.frame(width: 100, height: 100, alignment: .center)
VStack(alignment: .center) {
Text("2300")
.font(.system(.title))
Text("Remaining")
.font(.system(.caption))
}
}
}
}