I want to change the button's scale and add a shadow effect when the button is clicked, but the added shadow effect is not complete, where is the problem, why is the shadow of the last button only complete?
#objc func ButtonOnClicking(_ sender:homePageBtn){
UIView.animate(withDuration: 0.3, delay: 0, usingSpringWithDamping: 0.3, initialSpringVelocity: 0.5, options: UIViewAnimationOptions.allowAnimatedContent, animations: {
sender.layer.masksToBounds = false
sender.transform = CGAffineTransform(scaleX: 1.1, y: 1.1)
sender.layer.shadowColor = ColorHellp.getColor("333333").cgColor
sender.layer.shadowOffset = CGSize(width: 0, height: 0)
sender.layer.shadowRadius = 4
sender.layer.shadowOpacity = 0.3
}) { (isfinished) in
print("finished")
}
}
I can see, that also for the first button the shadow is complete, but it looks like, that the button is under the other ones.
So try something like bringSubViewToFront or change the z-index.
Related
I am trying to figure out why UIView.animate does not work as intended.
I know with UIView.animateKeyframes I can chain multiple types of animations together, but in this instance I am doing just one animation transform from the current size to 0.0.
The spinner image is already spinning using CABasicAnimation prior to this transform using:
let spinAnimation = CABasicAnimation(keyPath: "transform.rotation.z")
spinAnimation.toValue = .pi * 2.0 // 360ยบ spin
spinAnimation.duration = 1.4
spinAnimation.repeatCount = Float.greatestFiniteMagnitude // Repeat forever in loops.
spinAnimation.isCumulative = true
spinAnimation.isRemovedOnCompletion = false
self.spinnerImageView.layer.add(spinAnimation, forKey: self.spinnerAnimationKey)
UIView KeyFrame Animation
UIView.animateKeyframes(withDuration: Constants.AnimationDuration.standard, delay: 0.0, options: .calculationModeLinear, animations: {
UIView.addKeyframe(withRelativeStartTime: 0.0, relativeDuration: 0.4, animations: {
self.spinner.transform = CGAffineTransform(scaleX: 0.0, y: 0.0)
})
}) { (_) in
super.endRefreshing()
}
UIView Animation
UIView.animate(withDuration: 0.4, delay: 0.0, options: .curveLinear, animations: {
self.spinner.transform = CGAffineTransform(scaleX: 0.0, y: 0.0)
}) { (_) in
super.endRefreshing()
}
The keyframe animation works as intended where it shows the animating image shrink to 0.0, but the standard animate just causes the image to disappear. Shouldn't they act in the same way or is it because the image already has a CABasicAnimation layer that is causing the animate to not work properly? I would prefer to use .animate since I am only doing a transformation.
I am learning swift, I was successfully able to do popup animation of an UIView as below code but now i want to do reverse of it. i.e the way the UIView was animated should go back on a button click, Like the view is shrinking and then disappears.
popupView.isHidden = false
popupInnerView.isHidden = false
popupInnerView.transform = CGAffineTransform(scaleX: 0, y: 0)
UIView.animate(withDuration: 1, delay: 0, options: .curveLinear, animations: {
self.popupView.alpha = 1.0;
self.popupInnerView.transform = .identity
}, completion: nil)
Check if this one works for you. I have bound the showing and hiding of popup to buttons but you can bind them to anything.
For this to work
Drag and drop a uiview(your popup) into dock of view controller (see picture)
Make outlet of your uiview(popup) in your view controller. I am calling it popupView
For showing popup with Animation use the code
#IBAction func btnShowPopupTapped(_ sender: UIButton) {
popupView.center = view.center
popupView.alpha = 1
popupView.transform = CGAffineTransform(scaleX: 0.8, y: 1.2)
self.view.addSubview(popupView)
UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 0.5, initialSpringVelocity: 0, options: [], animations: {
//use if you want to darken the background
//self.viewDim.alpha = 0.8
//go back to original form
self.popupView.transform = .identity
})
}
And for hiding the popup
#IBAction func btnHideMeTapped(_ sender: Any) {
UIView.animate(withDuration: 0.3, delay: 0, usingSpringWithDamping: 0.5, initialSpringVelocity: 0, options: [], animations: {
//use if you wish to darken the background
//self.viewDim.alpha = 0
self.popupView.transform = CGAffineTransform(scaleX: 0.2, y: 0.2)
}) { (success) in
self.popupView.removeFromSuperview()
}
}
Note: If you want to darken the background as in gif.
Drag and drop a uiview into your view heirarchy (view dim). see the pic
pin to 0, 0 , 0 ,0 to the main view
set its background color to black
set is alpha to 0
uncomment the line (self.viewDim.alpha = 0.8) in "btnShowPopupTapped" Action
uncomment the line (self.viewDim.alpha = 0) in "btnHideMeTapped" Action
Let me know if this helps.
Try This
For Zoom in
UIView.animate(withDuration: 1, delay: 0, options: .curveLinear, animations: {
self.popupInnerView.transform = CGAffineTransform(scaleX: 0.001, y: 0.001)
}, completion: { _ in
self.popupInnerView.transform = CGAffineTransform(scaleX: 0.0, y: 0.0)
})
For Zoom Out
UIView.animate(withDuration: 1, delay: 0, options: .curveLinear, animations: {
self.popupInnerView.transform = CGAffineTransform(scaleX: 1.0, y: 1.0)
}, completion: nil)
This code worked for Pop Out
UIView.animate(withDuration: 1, delay: 0, options: .curveLinear, animations: {
self.popupView.alpha = 0.0;
self.popupInnerView.transform = CGAffineTransform(scaleX: 0.1, y: 0.1)
}, completion: { _ in
self.popupView.isHidden = true
self.popupInnerView.isHidden = true
})
How can I create an animation like in the following link?
Link
I'm using the below for animate cell from left in tableview delegate method willdisplaycell. Issue is all the cells are animating at a time not one after other, can anyone advice me how can I achieve that?
let direction:CGFloat = -1.0
cell?.layer.opacity = 0.4
cell?.transform = CGAffineTransform(translationX: (cell?.bounds.size.width)! * direction, y: 0)
UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 0.85, initialSpringVelocity: 0.8, options: [], animations: {
cell?.transform = CGAffineTransform.identity
cell?.contentView.layer.opacity = 1.0
}) { _ in
self.isForExpand = false
}
I have a UIButton, and I would like to change its text by accessing its titleLabel attribute. However, the way I want the button to change text is by first shrinking down to a very tiny size, then changing instantly while it's invisible, then scaling back up. After looking through multiple posts on here, I have reached this:
let changeText = CATransition();
changeText.type = kCATransitionReveal;
changeText.duration = 0.0;
changeText.timingFunction = CAMediaTimingFunction(name:kCAMediaTimingFunctionLinear);
submitButton.titleLabel?.layer.add(changeText, forKey: "changeTextTransition");
UIView.animateKeyframes(withDuration: 0.6, delay: 0, options: .calculationModeLinear, animations: {
//Zzzeeeewwwwwwwwww
UIView.addKeyframe(withRelativeStartTime: 0.0, relativeDuration: 0.5, animations: {
self.submitButton.titleLabel?.transform = self.submitButton.titleLabel!.transform.scaledBy(x: 0.001, y: 0.001);
})
UIView.addKeyframe(withRelativeStartTime: 0.5, relativeDuration: 0.0, animations: {
self.submitButton.titleLabel?.text = "Green";
})
//Wwwwwweeeeeeyyyyyppp
UIView.addKeyframe(withRelativeStartTime: 0.5, relativeDuration: 0.5, animations: {
self.submitButton.titleLabel?.transform = self.submitButton.titleLabel!.transform.scaledBy(x: 1000, y: 1000);
})
}, completion: nil)
The problem is that this doesn't work. What I get is a quick flash of the words "New Text" as the label shrinks, and then when it scales back up, it's still "Old Text". It's so weird I can't even begin to wrap my head around what might be the cause. I think what's happening is that it plays the reveal transition on the new text before it even shrinks down (No idea why since I specified duration=0), then grows back the old text.
Here is what it looks like (with some background color change that I omitted above):
First off, congratulations for including sound effects in your code comments, glad it's not just me that does that.
The text property of a label cannot be animated, so it is applied immediately, spoiling your animation.
One solution, which I use a lot for complex animations, is to use snapshots. At the start of the animation, create a snapshot of the label, then set the alpha of the label to zero and update the text. Then, animate the transforms of the label and snapshot together, when they're small, make the label visible and the snapshot invisible, then animate back up.
That sounds more complicated than it is, here's code to run it in a playground:
import UIKit
import PlaygroundSupport
let view = UIView(frame: CGRect(x: 0, y: 0, width: 400, height: 400))
view.backgroundColor = .blue
PlaygroundPage.current.liveView = view
let label = UILabel(frame: CGRect(x: 100, y: 100, width: 200, height: 200))
label.text = "Hello"
label.font = UIFont.systemFont(ofSize: 50)
label.textAlignment = .center
label.textColor = .white
view.addSubview(label)
let snapshot = label.snapshotView(afterScreenUpdates: true)!
view.addSubview(snapshot)
snapshot.frame = label.frame
label.alpha = 0
label.text = "Goodbye"
UIView.animateKeyframes(withDuration: 2, delay: 0, options: [.repeat, .autoreverse], animations: {
UIView.addKeyframe(withRelativeStartTime: 0, relativeDuration: 0.45) {
label.transform = CGAffineTransform(scaleX: 0.01, y: 0.01)
snapshot.transform = label.transform
}
UIView.addKeyframe(withRelativeStartTime: 0.45, relativeDuration: 0.1) {
label.alpha = 1.0
snapshot.alpha = 0.0
}
UIView.addKeyframe(withRelativeStartTime: 0.55, relativeDuration: 0.45) {
label.transform = CGAffineTransform.identity
}
}) { _ in
snapshot.removeFromSuperview()
}
Which gives you this result:
It's not clear to me what you are trying to do with the CATransition - unless there's another effect you're looking for as well, that isn't helping your cause.
I have a UIButton that I have placed in the center of the screen using Interface Builder.
I want to animate the UIButton to move up and down and repeat the animation forever.
So far I have this in my didMoveToView:
UIView.animateWithDuration(3, animations: { () -> Void in
self.playBtn.transform = CGAffineTransformMakeTranslation(0, 10)
self.playBtn.transform = CGAffineTransformMakeTranslation(0, -10)
self.playBtn.transform = CGAffineTransformMakeTranslation(0, -10)
self.playBtn.transform = CGAffineTransformMakeTranslation(0, 10)
UIView.setAnimationRepeatCount(-1)
})
However it only runs the first line and moves the button down 10.
You can't change the transform to multiple things simultaneously. I would expect your code to cause no animation at all, as changing the transform more than once would cancel the animation.
Another problem with your code is that what you're saying is not how you ask for a repeating animation.
Still another problem is that you won't ever bring the button back to its starting place; the transforms are not additive.
What you need to do is chain animations together. This will be easiest if you drop down to Core Animation and make a grouped animation.
Or can do it with view animation by doing a keyframe animation, perhaps; this is not identical to what you want, but it will get you started:
Swift 2
let opts = UIViewKeyframeAnimationOptions.Repeat
UIView.animateKeyframesWithDuration(3, delay: 0, options: opts, animations: {
UIView.addKeyframeWithRelativeStartTime(0, relativeDuration: 0.5, animations: {
self.playBtn.transform = CGAffineTransformMakeTranslation(0, 10)
})
UIView.addKeyframeWithRelativeStartTime(0.5, relativeDuration: 0.5, animations: {
self.playBtn.transform = CGAffineTransformIdentity
})
}, completion: nil)
Swift 3,4,5
let opts = UIView.KeyframeAnimationOptions.repeat
UIView.animateKeyframes(withDuration: 3, delay: 0, options: opts, animations: {
UIView.addKeyframe(withRelativeStartTime: 0, relativeDuration: 0.5, animations: {
self.playBtn.transform = CGAffineTransform(translationX: 0, y: 10)
})
UIView.addKeyframe(withRelativeStartTime: 0.5, relativeDuration: 0.5, animations: {
self.playBtn.transform = CGAffineTransform.identity
})
}, completion: nil)
But really, it would be better if you learned how animation actually works before you get into this kind of thing. From your code, it appears to me you are just thrashing.