I am creating a board game where each board piece is an instance of a view controller. I have subclassed UIStoryboardSegue so that each piece smoothly flows from one to the other. However, my game piece stays centered in this frame during the transition. I would like to have it so that my gamePiece (a UIImageView) stays in the center of the screen throughout the entire transition, but haven't had any luck searching.
Here is my Segue subclass, if it helps at all:
import UIKit
import QuartzCore
class RightToLeftSegue: UIStoryboardSegue {
override func perform() {
let src: UIViewController = self.sourceViewController
let dst: UIViewController = self.destinationViewController
let transition: CATransition = CATransition()
let timeFunc : CAMediaTimingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear)
transition.duration = 1.25
transition.timingFunction = timeFunc
transition.type = kCATransitionPush
transition.subtype = kCATransitionFromLeft
src.navigationController!.view.layer.addAnimation(transition, forKey: kCATransition)
src.navigationController!.pushViewController(dst, animated: true)
}
}
You can add this UIImageView to the window as subview before the transition happens.This way you will have it throughout the transition.
Let me know if this works out for you.
Related
i'm trying to present in my ViewController(which i will call main VC) and a MenuViewController . I've created MenuViewController with 1 view(which i've set like clear) and 2 views in it(1 is with tableView and button; second is bgcolor black with alpha 0.3).
PictureOfMenuViewController
What I'm trying to do:
to OVERLAY this menuVC on my ViewController with animation from right to left
I tried to do it (in my main VC) , like this :
#IBAction func menuButtonTapped(_ sender: Any) {
menuViewController = MenuViewController()
let transition = CATransition()
transition.duration = 1
transition.type = CATransitionType.push
transition.subtype = CATransitionSubtype.fromRight
view.window?.layer.add(transition, forKey: kCATransition)
self.present(menuViewController, animated: false)
but it PUSHES it instead of overlaying , and doing like screenshot of mainVC
My question is : how can i create an animation from right to left, is it possible , or like custom CATransitionType??
So I'm trying to animate the tractions between my UIViewControllers. I want the new VC to push in from the same side that the button is located on. I have managed to push in one VC from the right, but when I try to push in from the left it will push in the same VC first then the new VC pops up.
Here is my code:
switch sender.view {
case settingsButton:
let settingScreen = SettingsVC()
settingScreen.modalPresentationStyle = .fullScreen
present(settingScreen, animated: false, completion: nil)
let transition = CATransition()
transition.duration = 0.7
transition.type = .moveIn
transition.subtype = .fromLeft
transition.timingFunction = CAMediaTimingFunction(name: .default)
view.window!.layer.add(transition, forKey: kCATransition)
case calendarButton:
let calendarScreen = CalendarVC()
calendarScreen.modalPresentationStyle = .fullScreen
self.present(calendarScreen, animated: false, completion: nil)
let transition = CATransition()
transition.duration = 0.5
transition.type = .moveIn
transition.subtype = .fromRight
transition.timingFunction = CAMediaTimingFunction(name: .easeInEaseOut)
view.window!.layer.add(transition, forKey: kCATransition)
default:
break
}
You shouldn't be using CATransition to achieve this. With that, you can animate view transitions, within a single UIViewController. UIViewController transitions are a bit different.
Apple has it's own API for UIViewController transitions, but it's very cumbersome.
The best solution, in my opinion, is to use Hero library from Github.
It doesn't have a steep learning curve, and this kind of simple animations can be easily achieved.
To me the transition from right to left while opening new view is the most essential part of iPhone UI. How can it be that nearly in 2020 there is no way to have it for transition between two ViewControllers? At least I could not find the way.
Due to reasons I am not using NavigationController in the app. Instead I just call self.present(newVC) to open new one and self.dismiss() to go back.
I just want the new ViewController to slide from the right, that's all.
Any hints?
It seems you want to slide from right to left.
So you can do it using a custom segue transition.
First Create CATransition extenstion than add layer to your segue .
func rightToLeft() -> CATransition {
self.duration = 0.1 //set the duration to whatever you'd like.
self.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
self.type = kCATransitionReveal
self.subtype = kCATransitionFromRight
return self
}
}
Implementation :
DispatchQueue.main.async { //make sure all UI updates are on the main thread.
nav?.view.layer.add(CATransition().rightToLeft(), forKey: nil)
nav?.pushViewController(YourViewController(), animated: false)
}
So you want just slide from right to left here is code :
let transition = CATransition()
transition.duration = 0.3
transition.type = CATransitionType.push
transition.subtype = CATransitionSubtype.fromRight
transition.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut)
view.window!.layer.add(transition, forKey: kCATransition)
let presentedVC = self.storyboard!.instantiateViewController(withIdentifier: "PresentingViewController") \\ view Controller identifire in storyboard
presentedVC.view.backgroundColor = UIColor.orange
present(presentedVC, animated: false, completion: nil)
Here is Sample project
I am using CATransition for the next view to present over another from right. Now i want to control this view transition using swipe gesture so that user can swipe from left to right and next view present on screen with the thumb speed and position . So that user can feel the realness
my transition code is
let storyboard : UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let vc : drawer = storyboard.instantiateViewControllerWithIdentifier("drawerID") as! drawer
let transition: CATransition = CATransition()
let timeFunc : CAMediaTimingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
transition.duration = 0.50
transition.timingFunction = timeFunc
transition.type = kCATransitionPush
transition.subtype = kCATransitionFromRight //kCATransitionFromLeft
self.navigationController!.view.layer.addAnimation(transition, forKey: kCATransition)
self.navigationController!.pushViewController(vc, animated: false)
Currently, I have a view controller presenting other view controller. What I'm trying to do is to recreate the default animation used when pushing a view controller.
My current approach is:
FirstViewController:
#IBAction private func push(sender: AnyObject) {
let vc = UIStoryboard(name: "Main", bundle: nil).instantiateViewControllerWithIdentifier("SecondViewController")
let transition = CATransition()
transition.duration = 0.5
transition.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
transition.type = kCATransitionPush
transition.subtype = kCATransitionFromRight
view.window?.layer.addAnimation(transition, forKey: kCATransition)
presentViewController(vc, animated: false, completion: nil)
}
SecondViewController:
#IBAction private func pop(sender: AnyObject) {
let transition = CATransition()
transition.duration = 0.5
transition.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
transition.type = kCATransitionPush
transition.subtype = kCATransitionFromLeft
view.window?.layer.addAnimation(transition, forKey: kCATransition)
dismissViewControllerAnimated(false, completion: nil)
}
It is almost working, but I have a weird behaviour, I'm having a kind of black screen/flash when transitioning between view controllers. I already tried changing window.backgroundColor but it is not fixing the issue.
Thanks in advance 0_0...
The trouble is merely that what you're doing is not how to customize the animation for a present/dismiss transition. Apple has provided you with a clear, well-establish, official way to do that, and what you're doing is not it. You need to give your presented view controller a transitioningDelegate along with implementations of animationControllerForPresentedController: and animationControllerForDismissedController:, and implement the UIViewControllerAnimatedTransitioning protocol, possibly along with a custom UIPresentationController subclass.