Performing segue after animation takes long - ios

I'm trying to perform a segue in the completion block of an animation in Swift. However, the segue takes a long time(about 10 seconds) to do and I'm not sure why. Here's the code:
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
imageViewAnimated.startAnimating()
if label.center != CGPoint(x:50, y:10) {
UIView.animateWithDuration(2.0, delay: 0.0, usingSpringWithDamping: 0.0, initialSpringVelocity: 0.0, options: .CurveEaseOut, animations: { () -> Void in
self.label.center = self.view.center
}, completion: nil)
UIView.animateWithDuration(0.5, delay: 0.0, usingSpringWithDamping: 0.0, initialSpringVelocity: 0.0, options: .CurveEaseOut, animations: { () -> Void in
self.label.alpha = 0.0
}, completion: { finished in
self.poof.alpha = 1.0
self.performSegueWithIdentifier("backSegue", sender: nil)
})
}
}

override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
imageViewAnimated.startAnimating()
if label.center != CGPoint(x:50, y:10) {
UIView.animateWithDuration(2.0, delay: 0.0, usingSpringWithDamping: 0.0, initialSpringVelocity: 0.0, options: .CurveEaseOut, animations: { () -> Void in
self.label.center = self.view.center
}, completion: nil)
UIView.animateWithDuration(0.5, delay: 0.0, usingSpringWithDamping: 0.0, initialSpringVelocity: 0.0, options: .CurveEaseOut, animations: { () -> Void in
self.label.alpha = 0.0
}, completion: { finished in
self.poof.alpha = 1.0
dispatch_async(dispatch_get_main_queue(),{
self.performSegueWithIdentifier("backSegue", sender: nil)
})
})
}
}

Related

Unwanted button preview before animation during transition to second controller

In a navigation controller embedded project, using animations, I cannot avoid getting a "fast preview" of the buttons present in the next ViewController, where those buttons will slide from left border of the screen to the center.
So, when I tap in first VC, see for an instant the buttons in second VC, and then the second VC appears and the animation works (and it works fine)
In home controller the button is:
#objc func imageTapped(tapGestureRecognizer: UITapGestureRecognizer)
{
print("tapped")
//animate 1/2
UIView.animate(withDuration: 0.8, animations: { () -> Void in
self.mainButtonContainerView.center.y -= self.view.bounds.width //self.view.frame.origin
self.mainButtonContainerView.isUserInteractionEnabled = false
self.mainButtonContainerView.alpha = 0.0
})
//animate2/2
DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(1) ) {
self.pushShowNextVC_ChoiceVC(dataToPass: "")
}
}
Then, the animation in second VC ViewDidLoad is:
for singleView in coantinersOutCollection {
//animation
singleView.center.x -= self.view.bounds.width
singleView.layer.cornerRadius = singleView.bounds.size.height/2
singleView.backgroundColor = UIColor.white
singleView.layer.borderColor = Constants.skyBlue3Color.cgColor
singleView.layer.borderWidth = 1
}
for singleLabel in labesForButtons {
singleLabel.textColor = Constants.skyBlue3Color
singleLabel.font = UIFont.boldSystemFont(ofSize: 17.0)
}
for singleImage in self.iconButtonImages {
// singleImage.image = UIImage(named: "")
singleImage.backgroundColor = UIColor.clear
singleImage.layer.borderWidth = 1
singleImage.layer.borderColor = Constants.skyBlue3Color.cgColor
}
UIView.animate(withDuration: 1.5, delay: 0.6,
usingSpringWithDamping: 0.6,
initialSpringVelocity: 1,
options: [], animations: {
self.containerDownloadButton.center.x += self.view.bounds.width
}, completion: nil)
UIView.animate(withDuration: 1.5, delay: 0.7,
usingSpringWithDamping: 0.6,
initialSpringVelocity: 1,
options: [], animations: {
self.containerUploadButton.center.x += self.view.bounds.width
}, completion: nil)
UIView.animate(withDuration: 1.5, delay: 0.8,
usingSpringWithDamping: 0.6,
initialSpringVelocity: 1,
options: [], animations: {
self.containerCallButton.center.x += self.view.bounds.width
}, completion: nil)
UIView.animate(withDuration: 1.5, delay: 0.9,
usingSpringWithDamping: 0.6,
initialSpringVelocity: 1,
options: [], animations: {
self.containerIdleButton.center.x += self.view.bounds.width
}, completion: nil)

iOS - Type 'UIView' has no member 'AnimationOptions'

I am using TextFieldEffects to add text inputs effects in my textField. it is showing an error
Type 'UIView' has no member 'AnimationOptions'
Here's code.
override open func animateViewsForTextEntry() {
borderLayer.frame.origin = CGPoint(x: 0, y: font!.lineHeight)
UIView.animate(withDuration: 0.2, delay: 0.3, usingSpringWithDamping: 0.8, initialSpringVelocity: 1.0, options: UIView.AnimationOptions.beginFromCurrentState, animations: ({
self.placeholderLabel.frame.origin = CGPoint(x: self.placeholderInsets.x, y: self.borderLayer.frame.origin.y - self.placeholderLabel.bounds.height)
self.borderLayer.frame = self.rectForBorder(self.borderThickness, isFilled: true)
}), completion: { _ in
self.animationCompletionHandler?(.textEntry)
})
}
override open func animateViewsForTextDisplay() {
if text!.isEmpty {
UIView.animate(withDuration: 0.35, delay: 0.0, usingSpringWithDamping: 0.8, initialSpringVelocity: 2.0, options: UIView.AnimationOptions.beginFromCurrentState, animations: ({
self.layoutPlaceholderInTextRect()
self.placeholderLabel.alpha = 1
}), completion: { _ in
self.animationCompletionHandler?(.textDisplay)
})
borderLayer.frame = rectForBorder(borderThickness, isFilled: false)
}
}
Here's a screenshot of the error.
How to solve this issue?
It should be UIViewAnimationOptions.beginFromCurrentState, at least in Xcode < version 10.
Try changing UIView.AnimationOptions.beginFromCurrentState to [.beginFromCurrentState].

iOS Disable Animation When Back Pressed

When i press back button, the animation starts again and i loose buttons on my screen.
Here is a gif for better understanding:
https://i.gyazo.com/9d2ec00152c614c94a2ab2c797e86e12.gif
eoverride func viewDidLoad() {
super.viewDidLoad()
std.center.x += view.bounds.width
prtl.center.x += view.bounds.width
.
.
}
override func viewWillAppear(_ animated: Bool)
{
UIView.animate(withDuration: 0.5, delay: 0.5, options: [], animations: {
self.std.center.x -= self.view.bounds.width
}, completion: nil)
UIView.animate(withDuration: 0.5, delay: 0.6, options: [], animations: {
self.prtl.center.x -= self.view.bounds.width
}, completion: nil)
.
.
}
How can i stop animation start again to prevent loosing buttons on the screen.
Thanks!
override func viewDidLoad() {
super.viewDidLoad()
std.center.x += view.bounds.width
prtl.center.x += view.bounds.width
.
.
UIView.animate(withDuration: 0.5, delay: 0.5, options: [], animations: {
self.std.center.x -= self.view.bounds.width
}, completion: nil)
UIView.animate(withDuration: 0.5, delay: 0.6, options: [], animations: {
self.prtl.center.x -= self.view.bounds.width
}, completion: nil)
}
Remove code from viewWillAppear and try this.
If you want to animate view only the first time when your view load then you need to call your code inside viewDidLoad()
//MARK: - Life cycle
override func viewDidLoad() {
super.viewDidLoad()
std.center.x += view.bounds.width
prtl.center.x += view.bounds.width
// Call your animation related code here
animateView()
}
func animateView(){
UIView.animate(withDuration: 0.5, delay: 0.5, options: [], animations: {
self.std.center.x -= self.view.bounds.width
}, completion: nil)
UIView.animate(withDuration: 0.5, delay: 0.6, options: [], animations: {
self.prtl.center.x -= self.view.bounds.width
}, completion: nil)
}
override func viewWillAppear(_ animated: Bool)
{
UIView.animate(withDuration: 0.5, delay: 0.5, options: [], animations: {
self.std.center.x = 0
}, completion: nil)
UIView.animate(withDuration: 0.5, delay: 0.6, options: [], animations: {
self.prtl.center.x = 0
}, completion: nil)
.
.
}
Or use a BOOL to check
let shouldAnimate = (self.prtl.center.x != 0)
if shouldAnimate ....

Consecutive fade in fade out animations

I'm trying to implement this animation where a UIButton fades out when a user saves a file. While the button fades out, a UIImageView of a check mark image fades in place of the button. Once the imageview has fully faded in, then it fades out and the button fades back in.
UIView.animateWithDuration(0.60, delay: 0.0, options: UIViewAnimationOptions.CurveEaseOut, animations: {
self.recButton.alpha = 0.0
}, completion: {
(value: Bool) in
UIView.animateWithDuration(0.60, delay: 0.0, options: UIViewAnimationOptions.CurveEaseIn, animations: {
self.checkView.alpha = 1.0
}, completion: {
(value: Bool) in
UIView.animateWithDuration(0.60, delay: 0.0, options: UIViewAnimationOptions.CurveEaseOut, animations: {
self.checkView.alpha = 0.0
}, completion: {
(value: Bool) in
UIView.animateWithDuration(0.60, delay: 0.0, options: UIViewAnimationOptions.CurveEaseIn, animations: {
self.recButton.alpha = 1.0
self.recButton.enabled = true
}, completion: nil)
})
})
})
While the method above does work, its not as smooth as I would like. Is there a better way to go about this?
You need four keyframes for the animation you want: button fade out, image fade in, image fade out, button fade in.
let button: UIButton
let checkmarkImage: UIImageView
button.alpha = 1.0
checkmarkImage = 0.0
UIView.animateKeyframesWithDuration(2.4, delay: 0, options: .CalculationModeLinear, animations: {
UIView.addKeyframeWithRelativeStartTime(0.0, relativeDuration: 0.25, animations: {
button.alpha = 0.0
})
UIView.addKeyframeWithRelativeStartTime(0.25, relativeDuration: 0.25, animations: {
checkmarkImage.alpha = 1.0
})
UIView.addKeyframeWithRelativeStartTime(0.5, relativeDuration: 0.25, animations: {
checkmarkImage.alpha = 0.0
})
UIView.addKeyframeWithRelativeStartTime(0.75, relativeDuration: 0.25, animations: {
button.alpha = 1.0
})
}, completion: nil)
This question raised my curiosity - this keyframe thing is pretty cool.

Swift: Load .Xib with animation

Currently I am loading a new .Xib of class CreateAnAccount: UIView form a button pressed on another view.
At the moment it immediately switches to the Xib which is great, but is there a way of animating this? below is the code in the button.
#IBAction func createAnAccount(sender: AnyObject) {
let createAnAccountView = NSBundle.mainBundle().loadNibNamed("CreateAnAccount", owner: self, options: nil)[0] as! CreateAnAccount
createAnAccountView.frame = CGRectMake(0, 0, UIScreen.mainScreen().applicationFrame.size.width, UIScreen.mainScreen().applicationFrame.size.height + 20)
createAnAccountView.loginHandler = loginHandler
self.addSubview(createAnAccountView)
println("Create An Account Pressed")
}
Swift 4. Just place your animation code into layoutSubviews func. Works perfect for me.
override func layoutSubviews() {
super.layoutSubviews()
animate()
}
func animate() {
self.transform = CGAffineTransform(scaleX: 0.3, y: 2)
UIView.animate(withDuration: 1, delay: 0, usingSpringWithDamping: 0.3, initialSpringVelocity: 0, options: [.allowUserInteraction, .curveEaseOut], animations: {
self.transform = .identity
})
self.alpha = 1
}
Swift 5. #coldembrace answer
func animate() {
self.view.transform = CGAffineTransform(scaleX: 0.3, y: 2)
UIView.animate(withDuration: 1, delay: 0, usingSpringWithDamping: 0.3, initialSpringVelocity: 0, options: [.allowUserInteraction, .curveEaseOut], animations: {
self.view.transform = .identity
})
self.view.alpha = 1
}
You can try like this
UIView.transitionWithView(self.view, duration: 0.5, options:UIViewAnimationOptions.CurveEaseInOut,animations: {self.view.addSubview(createAnAccountView)}, completion: nil)
Moreover you change the UIViewAnimationOptions to have a desired effect.

Resources