ViewController 幻灯片动画
ViewController slide animation
我想在 tabswitch[1] 上创建类似 iOS 应用程序 facebook 的动画。我已经尝试开发某种动画,出现的问题是旧视图控制器直接在开关上变得不可见,而不是在新控制器快速滑入时慢慢淡出。
我发现了这个 SO 问题 但是正确标记的解决方案对我来说并不适用(它不是幻灯片,它是淡入淡出过渡)。我还想得到的是向左或向右滑动以切换选项卡的功能。就像在旧版本的 facebook 上一样。
到目前为止我得到的是:
extension TabBarController: UITabBarControllerDelegate {
func tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) -> Bool {
guard let fromView = selectedViewController?.view,
let toView = viewController.view else { return false }
if fromView != toView {
toView.transform = CGAffineTransform(translationX: -90, y: 0)
UIView.animate(withDuration: 0.25, delay: 0.0, options: .curveEaseInOut, animations: {
toView.transform = CGAffineTransform(translationX: 0, y: 0)
})
}; return true
}
}
class TabBarController: UITabBarController {
override func viewDidLoad() {
super.viewDidLoad()
delegate = self
}
}
如何解决这个问题?
[1]
我非常想从 Facebook 应用程序添加 gif。问题是我不想审查视频,只是想透露太多我的数据。 (即使 fb 已经有了它们)。同样在 youtube 上我没有找到合适的录音。请在 iOS.
的 fb 应用程序中自己尝试
你可以使用下面的思路:https://samwize.com/2016/04/27/making-tab-bar-slide-when-selected/
此外,这里的代码已更新到 Swift 4.1,我还删除了强制展开:
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
})
}
}
因此,您需要子类化 UITabBarController 并且您还必须编写动画部分,您可以调整动画选项(延迟、持续时间等)。
希望对你有所帮助,干杯!
我从没见过 Facebook,所以我不知道动画是什么。但是当标签栏控制器更改其选项卡(子视图控制器)时,您可以拥有任何动画Apple 提供的内置机制,用于将自定义动画添加到视图控制器之间的转换。它叫做自定义过渡动画。
Apple 于 2013 年首次引入了此机制。这是他们的视频 link:https://developer.apple.com/videos/play/wwdc2013/218/
我立即在我的应用程序中采用了这一点,我认为这让它们看起来更漂亮了。这是我喜欢的标签栏控制器自定义转换的演示:
真正酷的是,一旦您决定了想要的动画,就可以很容易地进行 交互式 转换(即用手势而不是单击按钮来驱动它) :
现在,您可能会说:好的,但这不是我想要的动画。没问题!一旦掌握了自定义过渡架构的窍门,将动画更改为您喜欢的任何内容就很容易了。在这个变体中,我只是注释掉一行,这样 "old" 视图控制器就不会滑开:
让您的想象力运行尽情发挥吧!采用自定义过渡动画,iOS 想要的方式。
如果你想要 pushViewController 导航的东西,你可以试试这个。
但是,当在 TabBarController 上的选项卡之间切换时,这将不起作用。为此,我会选择@mihai-erős 的解决方案
根据您的喜好更改动画持续时间,并将此 class 分配给您的导航转场,用于幻灯片动画。
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)
})
}
}
我想在 tabswitch[1] 上创建类似 iOS 应用程序 facebook 的动画。我已经尝试开发某种动画,出现的问题是旧视图控制器直接在开关上变得不可见,而不是在新控制器快速滑入时慢慢淡出。
我发现了这个 SO 问题
到目前为止我得到的是:
extension TabBarController: UITabBarControllerDelegate {
func tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) -> Bool {
guard let fromView = selectedViewController?.view,
let toView = viewController.view else { return false }
if fromView != toView {
toView.transform = CGAffineTransform(translationX: -90, y: 0)
UIView.animate(withDuration: 0.25, delay: 0.0, options: .curveEaseInOut, animations: {
toView.transform = CGAffineTransform(translationX: 0, y: 0)
})
}; return true
}
}
class TabBarController: UITabBarController {
override func viewDidLoad() {
super.viewDidLoad()
delegate = self
}
}
如何解决这个问题?
[1] 我非常想从 Facebook 应用程序添加 gif。问题是我不想审查视频,只是想透露太多我的数据。 (即使 fb 已经有了它们)。同样在 youtube 上我没有找到合适的录音。请在 iOS.
的 fb 应用程序中自己尝试你可以使用下面的思路:https://samwize.com/2016/04/27/making-tab-bar-slide-when-selected/
此外,这里的代码已更新到 Swift 4.1,我还删除了强制展开:
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
})
}
}
因此,您需要子类化 UITabBarController 并且您还必须编写动画部分,您可以调整动画选项(延迟、持续时间等)。
希望对你有所帮助,干杯!
我从没见过 Facebook,所以我不知道动画是什么。但是当标签栏控制器更改其选项卡(子视图控制器)时,您可以拥有任何动画Apple 提供的内置机制,用于将自定义动画添加到视图控制器之间的转换。它叫做自定义过渡动画。
Apple 于 2013 年首次引入了此机制。这是他们的视频 link:https://developer.apple.com/videos/play/wwdc2013/218/
我立即在我的应用程序中采用了这一点,我认为这让它们看起来更漂亮了。这是我喜欢的标签栏控制器自定义转换的演示:
真正酷的是,一旦您决定了想要的动画,就可以很容易地进行 交互式 转换(即用手势而不是单击按钮来驱动它) :
现在,您可能会说:好的,但这不是我想要的动画。没问题!一旦掌握了自定义过渡架构的窍门,将动画更改为您喜欢的任何内容就很容易了。在这个变体中,我只是注释掉一行,这样 "old" 视图控制器就不会滑开:
让您的想象力运行尽情发挥吧!采用自定义过渡动画,iOS 想要的方式。
如果你想要 pushViewController 导航的东西,你可以试试这个。
但是,当在 TabBarController 上的选项卡之间切换时,这将不起作用。为此,我会选择@mihai-erős 的解决方案
根据您的喜好更改动画持续时间,并将此 class 分配给您的导航转场,用于幻灯片动画。
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)
})
}
}