I need some help. I created the following reusable view, let's call it MyCustomCapsuleView
:
Nothing special, just a Text
with a Capsule
in the background. This view will have a different look when the user turns it on.
When the user turns it on, MyCustomCapsuleView
padding should increase to 17 to account for the extra space needed for the new look. Also, it should:
- Scale up and back
- Start wiggling
When the user turns it off, MyCustomCapsuleView
padding should go back to 3, as the extra room is not needed anymore. Also, it should:
- Stop wiggling
- Scale up and down, again
I was able to get a functional version of this, but the paddings are not working properly. When MyCustomCapsuleView
is wiggling, the paddings go back and forth between 3 and 17 (see the yellow background).
Any ideas what am I doing wrong? How can I achieve the behaviour I need? Note: Since this view is reusable, I need that the "turned off" version of my view keeps padding = 3. I will use it across different parts of my app and only in some places the "turned on/off" version will be available, and only in those places the padding for my view is 17.
Why the rotation (wiggle effect) looks so weird? I tried different anchor unit poi.ts (center, trailing, etc) and none of them seems to give me a good look.
Thanks for your help!
Here's my code:
struct MyCustomCapsuleView: View {
@State private var scaleUp = false
var showRemove: Bool
private var fillColor: Color { return Color(#colorLiteral(red: 0.4745098054, green: 0.8392156959, blue: 0.9764705896, alpha: 1)) }
private var foregroundColor: Color { return Color(#colorLiteral(red: 0.1019607857, green: 0.2784313858, blue: 0.400000006, alpha: 1)) }
var body: some View {
ZStack(alignment: .topTrailing) {
Text("Hello World!")
.foregroundColor(foregroundColor)
.padding(.horizontal)
.padding(.vertical, 10)
.lineLimit(1)
.background(
ZStack {
Capsule(style: RoundedCornerStyle.continuous)
.fill(fillColor)
Capsule(style: RoundedCornerStyle.continuous)
.stroke(foregroundColor, lineWidth: 2)
}
)
Circle()
.fill(Color.red)
.frame(width: 30, height: 30)
.overlay(
Image(systemName: "multiply")
.resizable()
.padding(7)
.foregroundColor(.white)
)
.offset(x: 15, y: -15)
.scaleEffect(showRemove ? 1 : 0, anchor: UnitPoint.topTrailing)
.animation(.spring(response: 0.3, dampingFraction: 0.6, blendDuration: 0), value: showRemove)
}
.padding(showRemove ? 17: 3)
.background(Color.yellow)
.scaleEffect(scaleUp ? 1.2 : 1)
.animation(.spring(response: 0.3, dampingFraction: 0.6, blendDuration: 0), value: scaleUp)
.rotationEffect(.degrees(showRemove ? 7 : 0), anchor: UnitPoint(x: 0.10, y: 0.0))
.animation(showRemove ? .easeInOut(duration: 1.15).repeatForever(autoreverses: true).delay(0.3) : .easeInOut(duration: 0.15), value: showRemove)
.onChange(of: showRemove, perform: { value in
if !scaleUp {
scaleUp = true
Timer.scheduledTimer(withTimeInterval: 0.1, repeats: false) { _ in
scaleUp = false
}
}
})
}
}
struct Test: View {
@State var showClose = false
var body: some View {
HStack {
MyCustomCapsuleView(showRemove: showClose)
Button("Turn On/Off") {
showClose.toggle()
}
}
}
}