I'm trying to add ripple effect to UIView using the code below.
let animation = CATransition()
animation.delegate = self
animation.duration = 2
animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
animation.type = "rippleEffect"
myView.layer.addAnimation(animation, forKey: nil)
Related
When working on this question, I notice that maybe fade of CATransitionType in CATransition is not working or broken. The rest of CATransitionType: moveIn, push, reveal works correctly.
I'm working on iPhone 13, iOS 16.0.
Code of the transition:
extension CALayer {
func makeFadeTransition() {
let transition = CATransition()
transition.timingFunction = CAMediaTimingFunction(name: .easeInEaseOut)
transition.duration = 0.5
transition.type = .fade
self.add(transition, forKey: nil)
}
}
Usage:
self.customView.layer.makeFadeTransition()
I know that we can switch to using UIView.animate combined with alpha to change opacity instead.
UIView.animate(withDuration: 0.15, animations: {
self.customView.alpha = 0.0
})
or using CABasicAnimation:
extension CALayer {
func makeFadeTransition() {
let transition = CABasicAnimation(keyPath: "opacity")
transition.timingFunction = CAMediaTimingFunction(name: .easeInEaseOut)
transition.duration = 0.5
transition.fromValue = 1.0
transition.toValue = 0.0
self.add(transition, forKey: nil)
}
}
But again, is CATransitionType type fade broken, or am I wrong at something?
You have to do something to change the layer...
For example, to fade-out / fade-in, we could do this:
extension CALayer {
func makeFadeTransition() {
let transition = CATransition()
transition.timingFunction = CAMediaTimingFunction(name: .easeInEaseOut)
// let's use duration of 2.5 to make it more obvious
transition.duration = 2.5
transition.type = .fade
// change the layer... opacity, backgroundColor, frame, etc
// fade transition doesn't like opacity of 0.0, so we'll use 0.01
self.opacity = self.opacity == 1.0 ? 0.01 : 1.0
// or, for example,
// "shrink" the layer by 20-points
//self.frame = self.frame.insetBy(dx: 20.0, dy: 20.0)
self.add(transition, forKey: nil)
}
}
I have found a nice curl view animation, and I'd like to add segue after finishing, but segue is calling first (and even if go back to viewcontroller I can see animation ends). Please help me find a mistake or the way to achieve my goal
UIView.animate(withDuration: 1, animations: {
let animation = CATransition()
animation.duration = 1
animation.startProgress = 0.0
animation.endProgress = 1
animation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut)
animation.type = CATransitionType(rawValue: "pageCurl")
animation.subtype = CATransitionSubtype(rawValue: "fromRight")
animation.isRemovedOnCompletion = false
animation.isRemovedOnCompletion = false
self.selectedCell!.view1.layer.add(animation, forKey: "pageFlipAnimation")
}, completion: { _ in
let secondViewController = self.storyboard?.instantiateViewController(withIdentifier: "PageVC") as? PageVC
secondViewController!.modalPresentationStyle = .fullScreen
self.navigationController?.present(secondViewController!, animated: false, completion: nil)
})
What you are doing is trying to animate the addition of animation to the view.
The animations block is taking 1 second to finish. Basically it is trying to animate the addition of animation in a second. On completion of that, it starts navigating.
Rather than doing that, you can use CATransaction to create the required functionality.
CATransaction.begin()
CATransaction.setCompletionBlock {
if let secondViewController = self.storyboard?.instantiateViewController(withIdentifier: "PageVC") as? PageVC {
secondViewController.modalPresentationStyle = .fullScreen
self.navigationController?.present(secondViewController, animated: false, completion: nil)
}
}
let animation = CATransition()
animation.duration = 1
animation.startProgress = 0.0
animation.endProgress = 1
animation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut)
animation.type = CATransitionType(rawValue: "pageCurl")
animation.subtype = CATransitionSubtype(rawValue: "fromRight")
animation.isRemovedOnCompletion = false
animation.isRemovedOnCompletion = false
self.selectedCell!.view1.layer.add(animation, forKey: "pageFlipAnimation")
CATransaction.commit()
In my project there is feature when user swipe on top bar one screen will appear with top to bottom animation
There are two view controller
oneviewcontroller.m
- (void)swipe
{
listViewController *list_obj=[[listViewController alloc] initWithNibName:#"listViewController" bundle:NULL];
UIViewAnimationTransition trans = UIViewAnimationTransitionCurlUp;
[UIView beginAnimations: nil context: nil];
[UIView setAnimationTransition: trans forView: [self.view window] cache: YES];
[self.navigationController pushViewController:list_obj animated:YES];
[UIView commitAnimations];
}
But this does not give the animation from top-bottom
I want to implement the navigation from
Push := top - bottom
Pop : = bottom - top
please help me
Thank you
You can push a view controller top to bottom like follows:
Obj-C:
- (void) pushVC:(UIViewController )dstVC {
CATransition *transition = [CATransition animation];
transition.duration = 0.5;
transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
transition.type = kCATransitionPush;
transition.subtype = kCATransitionFromTop;
[self.navigationController.view.layer addAnimation:transition forKey:kCATransition];
[self.navigationController pushViewController:dstVC animated:NO];
}
Use the below code to pop view controller from Bottom to Top:
- (void) popVC {
CATransition *transition = [CATransition animation];
transition.duration = 0.5;
transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
transition.type = kCATransitionFade;
transition.subtype = kCATransitionFromBottom;
[self.navigationController.view.layer addAnimation:transition forKey:kCATransition];
[self.navigationController popViewControllerAnimated:NO];
}
Swift 3:
func open() {
let settingsVC = SettingsVC()
let transition = CATransition()
transition.duration = 0.5
transition.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
transition.type = kCATransitionPush
transition.subtype = kCATransitionFromTop
navigationController?.view.layer.add(transition, forKey: kCATransition)
navigationController?.pushViewController(settingsVC, animated: false)
}
func close() {
let transition = CATransition()
transition.duration = 0.5
transition.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
transition.type = kCATransitionFade
transition.subtype = kCATransitionFromBottom
navigationController?.view.layer.add(transition, forKey:kCATransition)
let _ = navigationController?.popViewController(animated: false)
}
In Objective-C, I want to dismiss modal ViewController from right to left.
Now I can move from left to right on modal.
But I don't know how to dismiss this modal VC from left to right like push screen transition.
Here is a code which moves from a-ViewController to b-ViewController.
bViewController *nextVC = [[bViewController alloc] initWithNibName:nil bundle:nil];
CATransition *transition = [CATransition animation];
transition.duration = 0.5;
transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
transition.type = kCATransitionPush ;
[transition setSubtype:kCATransitionFromLeft];
[[nextVC.view layer] addAnimation:transition forKey:#"TransitionTest"];
//[self presentViewController:nextVC animated:YES completion:nil];
//if it's possible, I want to use upside's cord.(don't addSubView) but I don't know how to do it)
[self.view addSubview:nextVC.view] ;
Objective-C
CATransition *transition = [CATransition animation];
transition.duration = 0.4;
transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
transition.type = kCATransitionPush;
transition.subtype = kCATransitionFromRight;
[self.view.window.layer addAnimation:transition forKey:nil];
[self dismissViewControllerAnimated:NO completion:nil];
Swift 5
let transition = CATransition()
transition.duration = 0.5
transition.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut)
transition.type = CATransitionType.push
transition.subtype = CATransitionSubtype.fromRight
self.view.window!.layer.add(transition, forKey: nil)
self.dismiss(animated: false, completion: nil)
In Swift 4, You may use Bellow code. It is Working for me..
let transition = CATransition()
transition.duration = 0.5
transition.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
transition.type = kCATransitionPush
transition.subtype = kCATransitionFromRight
self.view.window!.layer.add(transition, forKey: nil)
self.dismiss(animated: false, completion: nil)
-(void) dismiss {
CATransition *transition = [CATransition animation];
transition.duration = 0.5;
transition.timingFunction =
[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
transition.type = kCATransitionMoveIn;
transition.subtype = kCATransitionFromRight;
UIView *containerView = self.view.window;
[containerView.layer addAnimation:transition forKey:nil];
[self dismissModalViewControllerAnimated:NO];
}
In Swift 3
let transition = CATransition()
transition.duration = 0.5
transition.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
transition.type = kCATransitionPush
transition.subtype = kCATransitionFromRight
view.layer.add(transition, forKey: "rightToLeftTransition")
dismiss(animated: true, completion: nil)
Define CATransition and implement the above implementation. This code can make screen transitions to the left and right using dismiss. The point is to make animated false. If you set animated to true, the original movement of dismiss is confused.
transition.duration = 0.5
transition.type = kCATransitionPush
transition.subtype = kCATransitionFromLeft
view.window!.layer.add(transition, forKey: kCATransition)
dismiss(animated: false, completion: nil)
I want to give my project customsegue effect on the cube.
UIStoryboardsegue this code. However cube effect does not happen. I wonder where did I go wrong?
import UIKit
import QuartzCore
class CubeSegue: UIStoryboardSegue {
override func perform() {
let source:UIViewController = self.sourceViewController as UIViewController
let destination:UIViewController = self.destinationViewController as UIViewController
let transition = CATransition()
transition.type = "cube"
transition.duration = 0.5
transition.subtype = kCATransitionFromRight
transition.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear)
self.sourceViewController.navigationController!!.pushViewController(self.destinationViewController as UIViewController, animated: true)
IS}
}
Thank you for your help.
I need to write code in this way has ..
override func perform() {
let source = self.sourceViewController as UIViewController;
let destination = self.destinationViewController as UIViewController;
let animation = CATransition()
animation.type = "cube"
animation.duration = 0.5
animation.subtype = kCATransitionFromRight
animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear)
source.navigationController?.view.layer.addAnimation(animation, forKey: kCATransition);
source.navigationController?.pushViewController(destination, animated: true);
}
}