ViewController slide animation

后端 未结 3 2042
花落未央
花落未央 2020-12-09 19:56

I want to create an animation like the iOS app facebook at tabswitch[1]. I have already tried to develop some kind of animation, the problem that

相关标签:
3条回答
  • 2020-12-09 20:21

    I've never seen Facebook so I don't know what the animation is. But you can have any animation you like when a tab bar controller changes its tab (child view controller), coherently and without any hacks, using the built-in mechanism that Apple provides for adding custom animation to a transition between view controllers. It's called custom transition animation.

    Apple first introduced this mechanism in 2013. Here's a link to their video about it: https://developer.apple.com/videos/play/wwdc2013/218/

    I immediately adopted this in my apps, and I think it makes them look a lot spiffier. Here's a demo of a tab bar controller custom transition that I like:

    The really cool thing is that once you've decided what animation you want, making the transition interactive (i.e. drive it with a gesture instead of a button click) is easy:

    Now, you might be saying: Okay, but that's not quite the animation I had in mind. No problem! Once you've got the hang of the custom transition architecture, changing the animation to anything you like is easy. In this variant, I just commented out one line so that the "old" view controller doesn't slide away:

    So let your imagination run wild! Adopt custom transition animations, the way that iOS intends.

    0 讨论(0)
  • 2020-12-09 20:33

    If you want something for pushViewController navigation, you can try this.

    However, when switching between tabs on a TabBarController, this will not work. For that, I'd go with @mihai-erős 's solution

    Change the Animation duration as per your liking, and assign this class to your navigation segues, for a Slide Animation.

    class CustomPushSegue: UIStoryboardSegue {
    
        override func perform() {
            // first get the source and destination view controllers as UIviews so that they can placed in navigation stack
    
            let sourceVCView = self.source.view as UIView!
            let destinationVCView = self.destination.view as UIView!
            let screenWidth = UIScreen.main.bounds.size.width
    
            //create the destination view's rectangular frame i.e starting at 0,0 and equal to screenwidth by screenheight
            destinationVCView?.transform = CGAffineTransform(translationX: screenWidth, y: 0)
    
            //the destinationview needs to be placed on top(aboveSubView) of source view in the app window stack before being accessed by nav stack
            // get the window and insert destination View
            let window = UIApplication.shared.keyWindow
            window?.insertSubview(destinationVCView!, aboveSubview: sourceVCView!)
    
    
            // the animation: first remove the source out of screen by moving it at the left side of it and at the same time place the destination to source's position
            // Animate the transition.
            UIView.animate(withDuration: 0.3, animations: { () -> Void in
                sourceVCView?.transform = CGAffineTransform(translationX: -screenWidth,y: 0)
                destinationVCView?.transform = CGAffineTransform.identity
    
            }, completion: { (Finished) -> Void in
                self.source.present(self.destination, animated: false, completion: nil)
            }) 
        }
    }
    
    0 讨论(0)
  • 2020-12-09 20:39

    You can use the following idea: https://samwize.com/2016/04/27/making-tab-bar-slide-when-selected/

    Also, here's the code updated to Swift 4.1 and I also removed the force unwrappings:

    import UIKit
    
    class MyTabBarController: UITabBarController {
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            delegate = self
        }
    }
    
    extension MyTabBarController: UITabBarControllerDelegate  {
        func tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) -> Bool {
            guard let tabViewControllers = tabBarController.viewControllers, let toIndex = tabViewControllers.index(of: viewController) else {
                return false
            }
            animateToTab(toIndex: toIndex)
            return true
        }
    
        func animateToTab(toIndex: Int) {
            guard let tabViewControllers = viewControllers,
                let selectedVC = selectedViewController else { return }
    
            guard let fromView = selectedVC.view,
                let toView = tabViewControllers[toIndex].view,
                let fromIndex = tabViewControllers.index(of: selectedVC),
                fromIndex != toIndex else { return }
    
    
            // Add the toView to the tab bar view
            fromView.superview?.addSubview(toView)
    
            // Position toView off screen (to the left/right of fromView)
            let screenWidth = UIScreen.main.bounds.size.width
            let scrollRight = toIndex > fromIndex
            let offset = (scrollRight ? screenWidth : -screenWidth)
            toView.center = CGPoint(x: fromView.center.x + offset, y: toView.center.y)
    
            // Disable interaction during animation
            view.isUserInteractionEnabled = false
    
            UIView.animate(withDuration: 0.3,
                           delay: 0.0,
                           usingSpringWithDamping: 1,
                           initialSpringVelocity: 0,
                           options: .curveEaseOut,
                           animations: {
                            // Slide the views by -offset
                            fromView.center = CGPoint(x: fromView.center.x - offset, y: fromView.center.y)
                            toView.center = CGPoint(x: toView.center.x - offset, y: toView.center.y)
    
            }, completion: { finished in
                // Remove the old view from the tabbar view.
                fromView.removeFromSuperview()
                self.selectedIndex = toIndex
                self.view.isUserInteractionEnabled = true
            })
        }
    }
    

    So, you need to subclass UITabBarController and you also have to write the animation part, you can tweak the animation options (delay, duration, etc).

    I hope it helps, cheers!

    0 讨论(0)
提交回复
热议问题