Circle stuck at top left hand corner of screen swiftUI - swift

I'm trying to draw a circle in SwiftUI at a constantly changing variable poseEstimator.bodyparts[.leftshoulder]!.location of type CGPoint on my View, and the end goal is that when the variable changes, I want the circle on the screen to move to the new coordinates stored in the variable.
I read up online on how to draw a circle in swiftUI and found out that you need to use the Circle() class to draw a circle, so that's what I did, but for some reason, my circle is always stuck at top left hand corner of the screen(0.0, 0.0), and even when I change the .position property of the circle to CGPoint(0.5,0.5), the circle is still stuck at the exact same location as before.
This is my swiftUI view struct:
import SwiftUI
struct StickFigureView: View { //declare the stickfigure for pose esimation as a swift view
#ObservedObject var poseEstimator: PoseEstimator
var size: CGSize
var body: some View {
if poseEstimator.bodyParts.isEmpty == false { //add in the sticks only if there are VNPoints stored in "bodyparts"
ZStack {
// Right leg
if poseEstimator.bodyParts[.rightAnkle]!.location != CGPoint(x: 0.0, y: 1.0) && poseEstimator.bodyParts[.rightKnee]!.location != CGPoint(x: 0.0, y: 1.0){
Stick(points: [poseEstimator.bodyParts[.rightAnkle]!.location,
poseEstimator.bodyParts[.rightKnee]!.location], size: size)
.stroke(lineWidth: 5.0)
.fill(Color.blue)
}
Circle()
.fill(Color.blue)
.frame(width: 10, height: 10)
.position(CGPoint(x: 0.5, y: 0.5)) // <- this is the circle which I have problems with
if poseEstimator.bodyParts[.rightKnee]!.location != CGPoint(x: 0.0, y: 1.0) && poseEstimator.bodyParts[.rightHip]!.location != CGPoint(x: 0.0, y: 1.0) && poseEstimator.bodyParts[.root]!.location != CGPoint(x: 0.0, y: 1.0) {
Stick(points: [poseEstimator.bodyParts[.rightKnee]!.location,
poseEstimator.bodyParts[.rightHip]!.location,
poseEstimator.bodyParts[.root]!.location], size: size)
.stroke(lineWidth: 5.0)
.fill(Color.blue)
}
// Left leg
if poseEstimator.bodyParts[.leftAnkle]!.location != CGPoint(x: 0.0, y: 1.0) && poseEstimator.bodyParts[.leftKnee]!.location != CGPoint(x: 0.0, y: 1.0){
Stick(points: [poseEstimator.bodyParts[.leftAnkle]!.location,
poseEstimator.bodyParts[.leftKnee]!.location], size: size)
.stroke(lineWidth: 5.0)
.fill(Color.blue)
}
if poseEstimator.bodyParts[.leftKnee]!.location != CGPoint(x: 0.0, y: 1.0) && poseEstimator.bodyParts[.leftHip]!.location != CGPoint(x: 0.0, y: 1.0) && poseEstimator.bodyParts[.root]!.location != CGPoint(x: 0.0, y: 1.0){
Stick(points: [poseEstimator.bodyParts[.leftKnee]!.location,
poseEstimator.bodyParts[.leftHip]!.location,
poseEstimator.bodyParts[.root]!.location], size: size)
.stroke(lineWidth: 5.0)
.fill(Color.blue)
}
// Right arm
if poseEstimator.bodyParts[.rightWrist]!.location != CGPoint(x: 0.0, y: 1.0) && poseEstimator.bodyParts[.rightElbow]!.location != CGPoint(x: 0.0, y: 1.0){
Stick(points: [poseEstimator.bodyParts[.rightWrist]!.location,
poseEstimator.bodyParts[.rightElbow]!.location], size: size)
.stroke(lineWidth: 5.0)
.fill(Color.blue)
}
if poseEstimator.bodyParts[.rightWrist]!.location != CGPoint(x: 0.0, y: 1.0) && poseEstimator.bodyParts[.rightElbow]!.location != CGPoint(x: 0.0, y: 1.0) && poseEstimator.bodyParts[.neck]!.location != CGPoint(x: 0.0, y: 1.0){
Stick(points: [poseEstimator.bodyParts[.rightElbow]!.location,
poseEstimator.bodyParts[.rightShoulder]!.location,
poseEstimator.bodyParts[.neck]!.location], size: size)
.stroke(lineWidth: 5.0)
.fill(Color.blue)
}
// Left arm
if poseEstimator.bodyParts[.leftWrist]!.location != CGPoint(x: 0.0, y: 1.0) && poseEstimator.bodyParts[.leftElbow]!.location != CGPoint(x: 0.0, y: 1.0){
Stick(points: [poseEstimator.bodyParts[.leftWrist]!.location,
poseEstimator.bodyParts[.leftElbow]!.location], size: size)
.stroke(lineWidth: 5.0)
.fill(Color.blue)
}
if poseEstimator.bodyParts[.leftElbow]!.location != CGPoint(x: 0.0, y: 1.0) && poseEstimator.bodyParts[.leftShoulder]!.location != CGPoint(x: 0.0, y: 1.0) && poseEstimator.bodyParts[.neck]!.location != CGPoint(x: 0.0, y: 1.0){
dot(Position: CGPoint(x: 0.5, y: 0.5), Color: Color.blue)
.position(CGPoint(x: 0.5, y: 0.5))
}
// Root to nose
if poseEstimator.bodyParts[.root]!.location != CGPoint(x: 0.0, y: 1.0) && poseEstimator.bodyParts[.neck]!.location != CGPoint(x: 0.0, y: 1.0){
Stick(points: [poseEstimator.bodyParts[.root]!.location,
poseEstimator.bodyParts[.neck]!.location], size: size)
.stroke(lineWidth: 5.0)
.fill(Color.blue)
}
}
}
}
}

Ok I've finally cracked the code. #jnpdx was right, the CGPoint that I set was too small to be even rendered in the first place. Upon further troubleshooting, I found out that the variable poseEstimator.bodyparts[.leftshoulder]!.location that I assigned to the position property of the circle was around 0.3, which was too small to be seen. I had to scale the variable using CGAffineTransform so that the CGpoint was relative to the width and height of the screen. This fixed the problem.
import SwiftUI
#available(iOS 15.0, *)
struct dotview: View { //declare the stickfigure for pose esimation as a swift view
#ObservedObject var poseEstimator: PoseEstimator
var size: CGSize
var body: some View {
if poseEstimator.bodyParts.isEmpty == false { //add in the sticks only if there are VNPoints stored in "bodyparts"
ZStack {
// Right leg
if poseEstimator.bodyParts[.rightAnkle]!.location != CGPoint(x: 0.0, y: 1.0) && poseEstimator.bodyParts[.rightKnee]!.location != CGPoint(x: 0.0, y: 1.0){
Circle()
.fill(poseEstimator.rightanklecolor)
.position(poseEstimator.bodyParts[.rightAnkle]!.location.applying(CGAffineTransform.identity.scaledBy(x: size.width, y: size.height)) .applying(CGAffineTransform(scaleX: -1, y: -1).translatedBy(x: -size.width, y: -size.height)))
.frame(width: 15, height: 15)
Circle()
.fill(poseEstimator.rightkneecolor)
.position(poseEstimator.bodyParts[.rightKnee]!.location.applying(CGAffineTransform.identity.scaledBy(x: size.width, y: size.height)) .applying(CGAffineTransform(scaleX: -1, y: -1).translatedBy(x: -size.width, y: -size.height)))
.frame(width: 15, height: 15)
}
if poseEstimator.bodyParts[.rightKnee]!.location != CGPoint(x: 0.0, y: 1.0) && poseEstimator.bodyParts[.rightHip]!.location != CGPoint(x: 0.0, y: 1.0) && poseEstimator.bodyParts[.root]!.location != CGPoint(x: 0.0, y: 1.0) {
Circle()
.fill(poseEstimator.rightkneecolor)
.position(poseEstimator.bodyParts[.rightKnee]!.location.applying(CGAffineTransform.identity.scaledBy(x: size.width, y: size.height)) .applying(CGAffineTransform(scaleX: -1, y: -1).translatedBy(x: -size.width, y: -size.height)))
.frame(width: 15, height: 15)
Circle()
.fill(poseEstimator.righthipcolor)
.position(poseEstimator.bodyParts[.rightHip]!.location.applying(CGAffineTransform.identity.scaledBy(x: size.width, y: size.height)) .applying(CGAffineTransform(scaleX: -1, y: -1).translatedBy(x: -size.width, y: -size.height)))
.frame(width: 15, height: 15)
}
// Left leg
if poseEstimator.bodyParts[.leftAnkle]!.location != CGPoint(x: 0.0, y: 1.0) && poseEstimator.bodyParts[.leftKnee]!.location != CGPoint(x: 0.0, y: 1.0){
Circle()
.fill(poseEstimator.leftanklecolor)
.position(poseEstimator.bodyParts[.leftAnkle]!.location.applying(CGAffineTransform.identity.scaledBy(x: size.width, y: size.height)) .applying(CGAffineTransform(scaleX: -1, y: -1).translatedBy(x: -size.width, y: -size.height)))
.frame(width: 15, height: 15)
Circle()
.fill(poseEstimator.leftkneecolor)
.position(poseEstimator.bodyParts[.leftKnee]!.location.applying(CGAffineTransform.identity.scaledBy(x: size.width, y: size.height)) .applying(CGAffineTransform(scaleX: -1, y: -1).translatedBy(x: -size.width, y: -size.height)))
.frame(width: 15, height: 15)
}
if poseEstimator.bodyParts[.leftKnee]!.location != CGPoint(x: 0.0, y: 1.0) && poseEstimator.bodyParts[.leftHip]!.location != CGPoint(x: 0.0, y: 1.0) && poseEstimator.bodyParts[.root]!.location != CGPoint(x: 0.0, y: 1.0){
Circle()
.fill(poseEstimator.leftkneecolor)
.position(poseEstimator.bodyParts[.leftKnee]!.location.applying(CGAffineTransform.identity.scaledBy(x: size.width, y: size.height)) .applying(CGAffineTransform(scaleX: -1, y: -1).translatedBy(x: -size.width, y: -size.height)))
.frame(width: 15, height: 15)
Circle()
.fill(poseEstimator.lefthipcolor)
.position(poseEstimator.bodyParts[.leftHip]!.location.applying(CGAffineTransform.identity.scaledBy(x: size.width, y: size.height)) .applying(CGAffineTransform(scaleX: -1, y: -1).translatedBy(x: -size.width, y: -size.height)))
.frame(width: 15, height: 15)
}
// Right arm
if poseEstimator.bodyParts[.rightWrist]!.location != CGPoint(x: 0.0, y: 1.0) && poseEstimator.bodyParts[.rightElbow]!.location != CGPoint(x: 0.0, y: 1.0){
Circle()
.fill(poseEstimator.rightwristcolor)
.position(poseEstimator.bodyParts[.rightWrist]!.location.applying(CGAffineTransform.identity.scaledBy(x: size.width, y: size.height)) .applying(CGAffineTransform(scaleX: -1, y: -1).translatedBy(x: -size.width, y: -size.height)))
.frame(width: 15, height: 15)
Circle()
.fill(poseEstimator.rightelbowcolor)
.position(poseEstimator.bodyParts[.rightElbow]!.location.applying(CGAffineTransform.identity.scaledBy(x: size.width, y: size.height)) .applying(CGAffineTransform(scaleX: -1, y: -1).translatedBy(x: -size.width, y: -size.height)))
.frame(width: 15, height: 15)
}
if poseEstimator.bodyParts[.rightElbow]!.location != CGPoint(x: 0.0, y: 1.0) && poseEstimator.bodyParts[.rightShoulder]!.location != CGPoint(x: 0.0, y: 1.0) && poseEstimator.bodyParts[.neck]!.location != CGPoint(x: 0.0, y: 1.0){
Circle()
.fill(poseEstimator.rightelbowcolor)
.position(poseEstimator.bodyParts[.rightElbow]!.location.applying(CGAffineTransform.identity.scaledBy(x: size.width, y: size.height)) .applying(CGAffineTransform(scaleX: -1, y: -1).translatedBy(x: -size.width, y: -size.height)))
.frame(width: 15, height: 15)
Circle()
.fill(poseEstimator.rightshouldercolor)
.position(poseEstimator.bodyParts[.rightShoulder]!.location.applying(CGAffineTransform.identity.scaledBy(x: size.width, y: size.height)) .applying(CGAffineTransform(scaleX: -1, y: -1).translatedBy(x: -size.width, y: -size.height)))
.frame(width: 15, height: 15)
}
// Left arm
if poseEstimator.bodyParts[.leftWrist]!.location != CGPoint(x: 0.0, y: 1.0) && poseEstimator.bodyParts[.leftElbow]!.location != CGPoint(x: 0.0, y: 1.0){
Circle()
.fill(poseEstimator.leftwristcolor)
.position(poseEstimator.bodyParts[.leftWrist]!.location.applying(CGAffineTransform.identity.scaledBy(x: size.width, y: size.height)) .applying(CGAffineTransform(scaleX: -1, y: -1).translatedBy(x: -size.width, y: -size.height)))
.frame(width: 15, height: 15)
Circle()
.fill(poseEstimator.leftelbowcolor)
.position(poseEstimator.bodyParts[.leftElbow]!.location.applying(CGAffineTransform.identity.scaledBy(x: size.width, y: size.height)) .applying(CGAffineTransform(scaleX: -1, y: -1).translatedBy(x: -size.width, y: -size.height)))
.frame(width: 15, height: 15)
}
if poseEstimator.bodyParts[.leftElbow]!.location != CGPoint(x: 0.0, y: 1.0) && poseEstimator.bodyParts[.leftShoulder]!.location != CGPoint(x: 0.0, y: 1.0) && poseEstimator.bodyParts[.neck]!.location != CGPoint(x: 0.0, y: 1.0){
Circle()
.fill(poseEstimator.leftelbowcolor)
.position(poseEstimator.bodyParts[.leftElbow]!.location.applying(CGAffineTransform.identity.scaledBy(x: size.width, y: size.height)) .applying(CGAffineTransform(scaleX: -1, y: -1).translatedBy(x: -size.width, y: -size.height)))
.frame(width: 15, height: 15)
Circle()
.fill(poseEstimator.leftshouldercolor)
.position(poseEstimator.bodyParts[.leftShoulder]!.location.applying(CGAffineTransform.identity.scaledBy(x: size.width, y: size.height)) .applying(CGAffineTransform(scaleX: -1, y: -1).translatedBy(x: -size.width, y: -size.height)))
.frame(width: 15, height: 15)
}
// Root to nose
if poseEstimator.bodyParts[.root]!.location != CGPoint(x: 0.0, y: 1.0) && poseEstimator.bodyParts[.neck]!.location != CGPoint(x: 0.0, y: 1.0){
Circle()
.fill(poseEstimator.rootcolor)
.position(poseEstimator.bodyParts[.root]!.location.applying(CGAffineTransform.identity.scaledBy(x: size.width, y: size.height)) .applying(CGAffineTransform(scaleX: -1, y: -1).translatedBy(x: -size.width, y: -size.height)))
.frame(width: 15, height: 15)
Circle()
.fill(poseEstimator.neckcolor)
.position(poseEstimator.bodyParts[.neck]!.location.applying(CGAffineTransform.identity.scaledBy(x: size.width, y: size.height)) .applying(CGAffineTransform(scaleX: -1, y: -1).translatedBy(x: -size.width, y: -size.height)))
.frame(width: 15, height: 15)
}
}
}
}
}

Related

How can I make a trim rotate in SWIFTUI?

I have a RoundedRectangle and I want to make the trim rotate forever and make a nice animation from it.
Tried to make a rotation effect and 3d rotation effect, but it didn't work
#State private var show = false
var body: some View {
ZStack {
RoundedRectangle(cornerRadius: 20, style: .continuous)
.foregroundColor(.gray.opacity(0.1))
.frame(width: 195, height: 50)
RoundedRectangle(cornerRadius: 20, style: .continuous)
.trim(from: 0.25, to: 0.5)
.stroke(style: StrokeStyle(lineWidth: 3, lineCap: .round))
.frame(width: show ? 50 : 200, height: show ? 200 : 50)
.rotationEffect(Angle(degrees: show ? 90 : 0))
.animation(.linear.delay(1).repeatForever(autoreverses: true),
value: show)
RoundedRectangle(cornerRadius: 20, style: .continuous)
.trim(from: 0.75, to: 1)
.stroke(style: StrokeStyle(lineWidth: 3, lineCap: .round))
.frame(width: show ? 50 : 200, height: show ? 200 : 50)
.rotationEffect(Angle(degrees: show ? 90 : 0))
.animation(.linear.delay(1).repeatForever(autoreverses: true),
value: show)
Text("title")
.foregroundStyle(LinearGradient(gradient: Gradient(colors: colors),
startPoint: .topLeading,
endPoint: .bottomTrailing))
}
.onAppear {
show.toggle()
}
THis is my code. Made it move, but not the desired way... could be smoother and like two snakes going one after the other one
Animate the changing of the trim offsets. Since it is difficult to animate past the boundaries of 0 and 1, use .rotation(Angle(degrees: 180)) to always stay within the boundaries of 0 and 1:
struct ContentView: View {
let colors = [Color.green, Color.blue]
#State private var offset = 0.0
var body: some View {
ZStack {
RoundedRectangle(cornerRadius: 20, style: .continuous)
.foregroundColor(.gray.opacity(0.1))
.frame(width: 195, height: 50)
RoundedRectangle(cornerRadius: 20, style: .continuous)
.trim(from: 0.25 + offset, to: 0.5 + offset)
.stroke(style: StrokeStyle(lineWidth: 3, lineCap: .round))
.frame(width: 195, height: 50)
RoundedRectangle(cornerRadius: 20, style: .continuous)
.trim(from: 0.25 + offset, to: 0.5 + offset)
.stroke(style: StrokeStyle(lineWidth: 3, lineCap: .round))
.rotation(Angle(degrees: 180))
.frame(width: 195, height: 50)
Text("title")
.foregroundStyle(LinearGradient(gradient: Gradient(colors: colors),
startPoint: .topLeading,
endPoint: .bottomTrailing))
}
.onAppear {
withAnimation(.linear(duration: 0.75).repeatForever(autoreverses: false)) {
offset = 0.5
}
}
}
}
Optimizing the code
Since the two "snakes" are identical except for the 180º rotation, we can code this with a ForEach:
ForEach([0.0, 180.0], id: \.self) { rotation in
RoundedRectangle(cornerRadius: 20, style: .continuous)
.trim(from: 0.25 + offset, to: 0.5 + offset)
.stroke(style: StrokeStyle(lineWidth: 3, lineCap: .round))
.rotation(Angle(degrees: rotation))
.frame(width: 195, height: 50)
}

SwiftUI: How to center a rectangle in a list?

How do I center the rectangles in the list? I have tried somethings in my code, with alignment, but it has no affect sadly. Has this something to do with the default behavior of a list?
Here is my code:
struct ContentView: View {
var sectiesList = [
Secties(name: "Algemeen", color: Color.overigPink),
Secties(name: "Natuurkunde", color: Color.natuurkundeBlue),
Secties(name: "Wiskunde", color: Color.wiskundeBrown),
Secties(name: "Scheikunde", color: Color.scheikundeRed),
Secties(name: "Biologie", color: Color.biologieGreen)
]
var body: some View {
NavigationView {
ZStack {
Color.offWhite
List(sectiesList, id: \.name) { secties in
ZStack(alignment: .center) {
RoundedRectangle(cornerRadius: 25)
.fill(secties.color)
.frame(width: UIScreen.screenWidth * 0.85, height: UIScreen.screenHeight * 0.13, alignment: .center)
.shadow(color: Color.black.opacity(0.2), radius: 10, x: 10, y: 10)
.shadow(color: Color.white.opacity(0.7), radius: 10, x: -5, y: -5)
Text(secties.name)
.font(.largeTitle)
.fontWeight(.semibold)
.foregroundColor(Color.white)
.multilineTextAlignment(.center)
}
}
}.navigationBarTitle(Text("Binas"))
}
}
init() {
UITableView.appearance().separatorStyle = .none
UITableViewCell.appearance().backgroundColor = UIColor(red: 225 / 255, green: 225 / 255, blue: 235 / 255, alpha: 1)
UITableView.appearance().backgroundColor = UIColor(red: 225 / 255, green: 225 / 255, blue: 235 / 255, alpha: 1)
}
}
Give ZStack max available space in row, like
ZStack(alignment: .center) {
RoundedRectangle(cornerRadius: 25)
.fill(secties.color)
.frame(width: UIScreen.screenWidth * 0.85, height: UIScreen.screenHeight * 0.13, alignment: .center)
.shadow(color: Color.black.opacity(0.2), radius: 10, x: 10, y: 10)
.shadow(color: Color.white.opacity(0.7), radius: 10, x: -5, y: -5)
Text(secties.name)
.font(.largeTitle)
.fontWeight(.semibold)
.foregroundColor(Color.white)
.multilineTextAlignment(.center)
}
.frame(maxWidth: .infinity) // << here !!

Image and Button title in VStack button

Code below in xcode swiftui will generate the BEFORE screen but I want to move the House image just above the "Houses" text (see AFTER screen), I have spent a full day on this and I can't figure out how to make it possible, if anyone is willing to step in for help will be much appreciated! Full code provided below...
Before and After VStack button
import SwiftUI
struct LightGreenButton: View {
var body: some View {
VStack {
Image(systemName: "house")
.resizable()
.frame(width: 50, height: 50, alignment: .center)
//.opacity(0.6)
.clipped()
.foregroundColor(Color(#colorLiteral(red: 0.005, green: 0.4422248602, blue: 0.3870742321, alpha: 1)))
.offset(x: 0, y: 0)
Text("Houses")
.font(.system(size: 20, weight: .semibold, design: .rounded))
.frame(width: 150, height: 100)
.foregroundColor(Color(#colorLiteral(red: 0.005, green: 0.4422248602, blue: 0.3870742321, alpha: 1)))
.background(
ZStack {
Color(#colorLiteral(red: 0.6574724317, green: 0.8923466802, blue: 0.8671938181, alpha: 1))
RoundedRectangle(cornerRadius: 16, style: .continuous)
.foregroundColor(.white)
.blur(radius: 4)
.offset(x: -8, y: -8)
RoundedRectangle(cornerRadius: 16, style: .continuous)
.fill(
LinearGradient(gradient: Gradient(colors: [Color(#colorLiteral(red: 0.6574724317, green: 0.8923466802, blue: 0.8671938181, alpha: 1)), Color.white]), startPoint: .topLeading, endPoint: .bottomTrailing)
)
.padding(2)
.blur(radius: 1)
}
)
.clipShape(RoundedRectangle(cornerRadius: 16, style: .continuous))
.shadow(color: Color(#colorLiteral(red: 0.8696053624, green: 0.8697276711, blue: 0.8695667386, alpha: 1)), radius: 20, x: 20, y: 20)
.shadow(color: Color(#colorLiteral(red: 1, green: 1, blue: 1, alpha: 1)), radius: 20, x: -20, y: -20)
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
.background(Color(#colorLiteral(red: 0.9447055279, green: 0.954059048, blue: 0.954059048, alpha: 1)))
.edgesIgnoringSafeArea(.all)
}
}
struct LightGreenButton_Previews: PreviewProvider {
static var previews: some View {
LightGreenButton()
}
}
Here is a solution. Tested with Xcode 11.4 / iOS 13.4.
struct LightGreenButton: View {
var body: some View {
VStack {
Image(systemName: "house")
.resizable()
.frame(width: 50, height: 50, alignment: .center)
//.opacity(0.6)
.clipped()
.foregroundColor(Color(#colorLiteral(red: 0.005, green: 0.4422248602, blue: 0.3870742321, alpha: 1)))
.offset(x: 0, y: 0)
Text("Houses")
.font(.system(size: 20, weight: .semibold, design: .rounded))
.foregroundColor(Color(#colorLiteral(red: 0.005, green: 0.4422248602, blue: 0.3870742321, alpha: 1)))
}
.frame(width: 150, height: 100)
.background(
ZStack {
Color(#colorLiteral(red: 0.6574724317, green: 0.8923466802, blue: 0.8671938181, alpha: 1))
RoundedRectangle(cornerRadius: 16, style: .continuous)
.foregroundColor(.white)
.blur(radius: 4)
.offset(x: -8, y: -8)
RoundedRectangle(cornerRadius: 16, style: .continuous)
.fill(
LinearGradient(gradient: Gradient(colors: [Color(#colorLiteral(red: 0.6574724317, green: 0.8923466802, blue: 0.8671938181, alpha: 1)), Color.white]), startPoint: .topLeading, endPoint: .bottomTrailing)
)
.padding(2)
.blur(radius: 1)
})
.clipShape(RoundedRectangle(cornerRadius: 16, style: .continuous))
.shadow(color: Color(#colorLiteral(red: 0.8696053624, green: 0.8697276711, blue: 0.8695667386, alpha: 1)), radius: 20, x: 20, y: 20)
.shadow(color: Color(#colorLiteral(red: 1, green: 1, blue: 1, alpha: 1)), radius: 20, x: -20, y: -20)
.frame(maxWidth: .infinity, maxHeight: .infinity)
.background(Color(#colorLiteral(red: 0.9447055279, green: 0.954059048, blue: 0.954059048, alpha: 1)))
.edgesIgnoringSafeArea(.all)
}
}

Swift animating view height

I am trying to chain 2 animations. But can not get the second animation (change of height) working.
1st try:
self.customView.frame = CGRect(x: 20, y: 0, width: width, height: 76)
UIView.animate(withDuration: 0.3, delay: 0, usingSpringWithDamping: 0.5, initialSpringVelocity: 1, options: .curveEaseInOut, animations: {
self.customView.frame = CGRect(x: 20, y: 20, width: 280, height: 76)
}, completion: { (finished: Bool) in
UIView.animate(withDuration: 0.3) {
self.customView.frame = CGRect(x: 20, y: 20, width: 280, height: 136)
}
})
2nd one:
self.customView.frame = CGRect(x: 20, y: 0, width: width, height: 76)
UIView.animate(withDuration: 0.3, delay: 0, usingSpringWithDamping: 0.5, initialSpringVelocity: 1, options: .curveEaseInOut, animations: {
self.customView.frame = CGRect(x: 20, y: 20, width: 280, height: 76)
}, completion: { (finished: Bool) in
UIView.animate(withDuration: 0.3) {
var heightConstraint = self.customView.heightAnchor.constraint(equalToConstant: 136)
heightConstraint.isActive = true
self.view.layoutIfNeeded()
}
})

How to make sure that an element does not exceed of screen in swiftUI?

I have a probleme that I can not manage in swiftUI : I have some elements in a VStack, a view goes beyond the screen, is normal, but my menu exceed also, it's normal behavior but not the desired result. I don't know how to bypass this result.
The component that exceed:
The component menu that must not exceed:
Code of the contentView.swift
import SwiftUI
struct ContentView : View {
var body: some View {
ZStack {
Rectangle()
.foregroundColor(.clear)
.background(LinearGradient(gradient: Gradient(colors: [Color(red: 189/255, green: 195/255, blue: 199/255, opacity: 1.0), .white]), startPoint: .topTrailing, endPoint: .bottomLeading),
cornerRadius: 0)
.edgesIgnoringSafeArea(.all)
VStack() {
ScreenTitle()
Spacer()
Sonar()
Spacer()
NavBar()
}
}
}
}
Code of sonar view:
import SwiftUI
struct Sonar : View {
#State private var sonarAtived: Bool = false
private var animationSonarCircleOne: Animation {
Animation.basic(duration: 0.2, curve: .easeInOut)
.delay(0)
}
private var animationSonarCircleTwo: Animation {
Animation.basic(duration: 0.2, curve: .easeInOut)
.delay(0.1)
}
private var animationSonarCircleThree: Animation {
Animation.basic(duration: 0.2, curve: .easeInOut)
.delay(0.25)
}
private var animationButtonSublay: Animation {
Animation.basic(duration: 0.7, curve: .easeInOut)
.repeatForever(autoreverses: true)
}
var body: some View {
HStack(spacing: 20) {
ZStack {
// Button sublay
Circle()
.animation(animationButtonSublay)
.frame(width: 130, height: 130)
.padding(10)
.foregroundColor(Color.init(red: 231/255, green: 76/255, blue: 60/255, opacity: 0.4))
.overlay(Circle().stroke(Color.init(red: 231/255, green: 76/255, blue: 60/255, opacity: self.sonarAtived ? 0.5 : 0), lineWidth: self.sonarAtived ? 30 : 0))
// Button
Button(action: {
self.sonarAtived.toggle()
}) {
Text("Enregistrer ma position")
.color(.white)
.lineLimit(nil)
.multilineTextAlignment(.center)
.font(.system(size: 22))
}
.frame(width: 130, height: 130)
.padding(10)
.background(Color.init(red: 231/255, green: 76/255, blue: 60/255, opacity: 1.0))
.overlay(Circle().stroke(Color.init(red: 192/255, green: 57/255, blue: 43/255, opacity: 1.0), lineWidth: 3))
.clipShape(Circle())
// Circles
Circle()
.animation(animationSonarCircleOne)
.frame(width: 250, height: 250, alignment: .center)
.overlay(Circle().stroke(Color.init(red: 52/255, green: 73/255, blue: 94/255, opacity: self.sonarAtived ? 0.18 : 0.0), lineWidth: 1))
.foregroundColor(Color.clear)
Circle()
.animation(animationSonarCircleTwo)
.frame(width: 400, height: 400, alignment: .center)
.overlay(Circle().stroke(Color.init(red: 52/255, green: 73/255, blue: 94/255, opacity: self.sonarAtived ? 0.15 : 0.0), lineWidth: 1))
.foregroundColor(Color.clear)
Circle()
.animation(animationSonarCircleThree)
.frame(width: 550, height: 600, alignment: .center)
.overlay(Circle().stroke(Color.init(red: 52/255, green: 73/255, blue: 94/255, opacity: self.sonarAtived ? 0.10 : 0.0), lineWidth: 1))
.foregroundColor(Color.clear)
}
}
}
}
Code of menu view, unwanted exceed:
import SwiftUI
struct NavBar : View {
var body: some View {
VStack {
Image("navigation_border")
.resizable()
.aspectRatio(contentMode: .fill)
HStack {
Spacer()
// Compass button
Button(action: {
// Code here
}) {
Image("ic_compass")
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: CGFloat(40), height: CGFloat(40), alignment: .center)
Text("Boussole")
.color(Color(red: 52/255, green: 73/255, blue: 94/255, opacity: 0.4))
.font(.system(size: 14))
}.frame(height: CGFloat(50), alignment: .bottomLeading)
Spacer()
// Travel button
Button(action: {
// Code here
}) {
Image("ic_travel")
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: CGFloat(40), height: CGFloat(40), alignment: .center)
Text("Parcours")
.color(Color(red: 52/255, green: 73/255, blue: 94/255, opacity: 0.4))
.font(.system(size: 14))
}.frame(height: CGFloat(50), alignment: .bottomLeading)
Spacer()
// Settings button
PresentationLink(destination: Settings()) {
Image("ic_settings")
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 35, height: 35, alignment: .center)
Text("Paramètres")
.color(Color(red: 52/255, green: 73/255, blue: 94/255, opacity: 0.4))
.font(.system(size: 14))
}.frame(height: 50, alignment: .bottomLeading)
Spacer()
}.frame(minWidth: 0, maxWidth: .infinity, minHeight: 70, maxHeight: 70, alignment: Alignment.center)
}.frame(minWidth: 0, maxWidth: .infinity, minHeight: 90, maxHeight: 90, alignment: Alignment.center)
}
}