remove label after it fades away - xcode

I have this code here where I show the label, have it fade away(which orks up to here) and then I want to remove it. Everything works fine untill i want to remove it. I need to remove it so i can run the whole process again.
Here is my code:
view.addSubview(minusLabel)
UIView.animateWithDuration(1.0, delay: 0.0, options: UIViewAnimationOptions.CurveEaseIn, animations: {
self.minusLabel.alpha = 0
}, completion: {
(finished: Bool) -> Void in
self.minusLabel.removeFromSuperview()
}
)

You shouldn't need to remove the the label to repeat the animation, try this code instead, and modify it to your likings:
func animate() {
UIView.animateWithDuration(1.0, animations: {
self.label.alpha = 1.0
//label is the name of your label which you have defined/created
}, completion: {
(Completed: Bool) -> Void in
UIView.animateWithDuration(1.0, delay: 0, options: UIViewAnimationOptions.CurveLinear, animations: {
self.label.alpha = 0
//label is the name of your label which you have defined/created
}, completion: {
(Completed: Bool) -> Void in
self.animate()
})
})
}
Whenever you want to call this function, use animate() and below it add label.alpha = 0 (Change label to the name of your label). Source: https://www.youtube.com/watch?v=iyg3u3z_fKI

Related

ChartJs linechart adddata animation

I am trying to make a 'Movie-Chart' with ChartJs v3.9.1 where I add and remove data:
https://codepen.io/ipax77/pen/YzLrNEM
<...>
let chartdata = { x: label, y: stepdata.Winrate };
chart.data.labels.push(label);
chart.data.datasets.forEach(dataset => {
if (dataset.label == stepdata.Commander) {
dataset.data.push(chartdata);
dataadded = true;
}
});
chart.update();
<...>
if (chart.data.labels.length > 6) {
let removelabel = chart.data.labels[0];
chart.data.labels.splice(0, 1);
chart.data.datasets.forEach(dataset => {
const index = dataset.data.findIndex(obj => obj.x == removelabel);
if (index > -1) {
dataset.data.splice(index, 1);
}
});
Somehow the animation for new datapoints starts from the xAxis rather than the previouse datapoint. Is there a way to fix this?
I tried working with timescale axis and chartjs-adapter-date-fns which fixes the problem, but then the animation for lines that don't start with the first label are messed up.
You could disable animation on the y-axis by defining options.animation as follows:
options: {
responsive: true,
animation: {
y: {
duration: 0
}
},

Im trying to make the effect loop with a 'while' and its not working

// API Reference: https://www.wix.com/velo/reference/api-overview/introduction
// “Hello, World!” Example: https://learn-code.wix.com/en/article/1-hello-world
import { timeline } from 'wix-animations';
$w.onReady(function () {
var rotate = true;
let timeline1 = timeline();
while ($w('#image1').onMouseIn(() => {
if (rotate == true) {
timeline1.add($w('#box2'), { opacity: 100, duration: 800, rotate: 3600 }).play();
rotate = false;
} else {
timeline1.replay();
rotate = true;
}
let i=0;
});
Adds an event handler that runs when the element is clicked.
Read more
#param {$w.MouseEvent} event
*/
export function image1_click(event) {
// This function was `added from the Properties & Events panel. To learn more, visit http://wix.to/UcBnC-4
// Add your code for this event here:
}

Is there a better way to implement a shake animation in swiftui?

I'm trying to get a button to shake when the user tries to log in without filling all the textfields in, and this is what I've come across so far:
struct Shake: GeometryEffect {
var amount: CGFloat = 10
var shakesPerUnit = 3
var animatableData: CGFloat
func effectValue(size: CGSize) -> ProjectionTransform {
ProjectionTransform(CGAffineTransform(translationX:
amount * sin(animatableData * .pi * CGFloat(shakesPerUnit)),
y: 0))
}
}
struct Correct: View {
#State var attempts: Int = 0
var body: some View {
VStack {
Rectangle()
.fill(Color.pink)
.frame(width: 200, height: 100)
.modifier(Shake(animatableData: CGFloat(attempts)))
Spacer()
Button(action: {
withAnimation(.default) {
self.attempts += 1
}
}, label: { Text("Login") })
}
}
}
However, this is particularly useless for a button, and even then the animation seems very off in that its pretty robotic. Can someone suggest an improvement so that I can get my button to shake?
try this
struct ContentView: View {
#State var selected = false
var body: some View {
VStack {
Button(action: {
self.selected.toggle()
}) { selected ? Text("Deselect") : Text("Select") }
Rectangle()
.fill(Color.purple)
.frame(width: 200, height: 200)
.offset(x: selected ? -30 : 0)
.animation(Animation.default.repeatCount(5).speed(6))
}
}
}
I do this to make the field shake and then gets back to it's original position:
private func signUp() {
if email.isEmpty {
withAnimation {
emailIsWrong = true
}
DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) {
withAnimation {
emailIsWrong = false
}
}
return
}
}
Where emailIsWrong is a #State variable:
#State private var emailIsWrong = false
Basically after 0.2 sec, I change the emailIsWrong back to false so the view goes back to its position. My text field looks like this:
TextField("Email", text: $email)
.padding()
.frame(height: 45)
.background(Color.white)
.colorScheme(.light)
.offset(x: emailIsWrong ? -8 : 0)
.animation(Animation.default.repeatCount(3, autoreverses: true).speed(6))
A little bit late to the party, but unfortunately the solutions here either finish the animation with a wrong offset or need some hardcoded assumption on the time the animation will finish.
The solution I came up with looks like this:
#State var shake = false
Text("Shake Me")
.font(.title)
.onTapGesture {
shake = true
}
.shake($shake) {
print("Finished")
}
To animate, you just need to set shake to true (it will automatically be set to false once the animation completes).
Here is the implementation:
struct Shake<Content: View>: View {
/// Set to true in order to animate
#Binding var shake: Bool
/// How many times the content will animate back and forth
var repeatCount = 3
/// Duration in seconds
var duration = 0.8
/// Range in pixels to go back and forth
var offsetRange = 10.0
#ViewBuilder let content: Content
var onCompletion: (() -> Void)?
#State private var xOffset = 0.0
var body: some View {
content
.offset(x: xOffset)
.onChange(of: shake) { shouldShake in
guard shouldShake else { return }
Task {
let start = Date()
await animate()
let end = Date()
print(end.timeIntervalSince1970 - start.timeIntervalSince1970)
shake = false
onCompletion?()
}
}
}
// Obs: some of factors must be 1.0.
private func animate() async {
let factor1 = 0.9
let eachDuration = duration * factor1 / CGFloat(repeatCount)
for _ in 0..<repeatCount {
await backAndForthAnimation(duration: eachDuration, offset: offsetRange)
}
let factor2 = 0.1
await animate(duration: duration * factor2) {
xOffset = 0.0
}
}
private func backAndForthAnimation(duration: CGFloat, offset: CGFloat) async {
let halfDuration = duration / 2
await animate(duration: halfDuration) {
self.xOffset = offset
}
await animate(duration: halfDuration) {
self.xOffset = -offset
}
}
}
extension View {
func shake(_ shake: Binding<Bool>,
repeatCount: Int = 3,
duration: CGFloat = 0.8,
offsetRange: CGFloat = 10,
onCompletion: (() -> Void)? = nil) -> some View {
Shake(shake: shake,
repeatCount: repeatCount,
duration: duration,
offsetRange: offsetRange) {
self
} onCompletion: {
onCompletion?()
}
}
func animate(duration: CGFloat, _ execute: #escaping () -> Void) async {
await withCheckedContinuation { continuation in
withAnimation(.linear(duration: duration)) {
execute()
}
DispatchQueue.main.asyncAfter(deadline: .now() + duration) {
continuation.resume()
}
}
}
}
here's my one
#State var ringOnFinish: Bool = false
#State var shakeOffset: Double = 0
Button() {
ringOnFinish.toggle()
//give it a little shake animation when off
if !ringOnFinish {
shakeOffset = 5
withAnimation {
shakeOffset = 0
}
} label: {
Image(systemName: "bell\(ringOnFinish ? "" : ".slash")")
.offset(x: ringOnFinish ? 0 : shakeOffset)
.animation(.default.repeatCount(3, autoreverses: true).speed(6), value: ringOnFinish)
}

how to do a simple scaling animation and why isn't this working?

i just read in stackoverflow i can only concatenate animation with delay, so i tried this here which simply shrinks and then scales the circle again. unfortunately the shrinking doesn't work!? if i comment out the growing, shrinking works...
struct ContentView: View {
#State var scaleImage : CGFloat = 1
var body: some View {
VStack {
Button(action: {
withAnimation(Animation.easeInOut(duration: 1)) {
self.scaleImage = 0.01
}
withAnimation(Animation.easeInOut(duration: 1).delay(1.0)) {
self.scaleImage = 1
}
}) {
Text ("Start animation")
}
Image(systemName: "circle.fill")
.scaleEffect(scaleImage)
}
}
}
Here is possible approach (based on AnimatableModifier). Actually it demonstrates how current animation end can be detected, and performed something - in this case, for your scaling scenario, just initiate reversing.
Simplified & modified your example
struct TestReversingScaleAnimation: View {
#State var scaleImage : CGFloat = 1
var body: some View {
VStack {
Button("Start animation") {
self.scaleImage = 0.01 // initiate animation
}
Image(systemName: "circle.fill")
.modifier(ReversingScale(to: scaleImage) {
self.scaleImage = 1 // reverse set
})
.animation(.default) // now can be implicit
}
}
}
Actually, show-maker here... important comments inline.
Updated for Xcode 13.3 (tested with iOS 15.4)
struct ReversingScale: AnimatableModifier {
var value: CGFloat
private let target: CGFloat
private let onEnded: () -> ()
init(to value: CGFloat, onEnded: #escaping () -> () = {}) {
self.target = value
self.value = value
self.onEnded = onEnded // << callback
}
var animatableData: CGFloat {
get { value }
set { value = newValue
// newValue here is interpolating by engine, so changing
// from previous to initially set, so when they got equal
// animation ended
let callback = onEnded
if newValue == target {
DispatchQueue.main.async(execute: callback)
}
}
}
func body(content: Content) -> some View {
content.scaleEffect(value)
}
}
Original variant (tested with Xcode 11.4 / iOS 13.4)
struct ReversingScale: AnimatableModifier {
var value: CGFloat
private var target: CGFloat
private var onEnded: () -> ()
init(to value: CGFloat, onEnded: #escaping () -> () = {}) {
self.target = value
self.value = value
self.onEnded = onEnded // << callback
}
var animatableData: CGFloat {
get { value }
set { value = newValue
// newValue here is interpolating by engine, so changing
// from previous to initially set, so when they got equal
// animation ended
if newValue == target {
onEnded()
}
}
}
func body(content: Content) -> some View {
content.scaleEffect(value)
}
}

Swift animatewithduration extra argument "delay" in call

func textFieldDidBeginEditing(textField: UITextField) {
let theWidth = view.frame.size
let theHeight = view.frame.size
if (UIScreen.mainScreen().bounds.height == 568) {
if (textField == self.profielnameTxt) {
UIView.animateWithDuration(0.3, delay: 0.0, options:UIViewAnimationOptions.CurveLinear, animations: {
self.view.center = CGPointMake(theWidth/2, (theHeight/2)-40)
}, completion: {
(finished:Bool) in
})
}
}
}
This is my code. and I keep getting extra arugument 'delay' in call when I try to build it. I am banging my head and searching google all over, but I can't find out where is wrong

Resources