iOSアプリのfacebookのようなアニメーションをtabswitch で作成したい[1]。私はすでにある種のアニメーションを開発しようとしましたが、新しいコントローラーが速くスライドしている間にゆっくりとフェードアウトするのではなく、古いビューコントローラーがスイッチ上で直接非表示になるという問題が発生します。
私はこれを見つけましたSO質問 CrossDissolveスライド遷移でタブバータブスイッチをアニメーション化する方法? しかし、正しいとマークされたソリューションは実際には機能しません(それはスライドではなく、フェードトランジションです。また、スライドを左または右に移動してタブを切り替える機能も必要です。旧バージョンの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を見たことがないので、アニメーションが何であるかわかりません。しかし、タブバーコントローラーがそのタブ(子ビューコントローラー)を変更するときにanyアニメーションを好きなように作成できますcoherentlyハックなしで、組み込みメカニズムを使用して= Appleは、ビューコントローラ間のトランジションにカスタムアニメーションを追加できるようにします。これはカスタムトランジションアニメーションと呼ばれます。
Appleはこのメカニズムを2013年に初めて導入しました。これに関するビデオへのリンクは次のとおりです。 https://developer.Apple.com/videos/play/wwdc2013/218/
私はすぐにこれを自分のアプリで採用しました。ここに私が好きなタブバーコントローラーのカスタム遷移のデモがあります:
本当にすばらしいのは、必要なアニメーションを決定したら、トランジションinteractive(つまり、ボタンをクリックする代わりにジェスチャーで操作する)を簡単に実行できることです。
さて、あなたは言っているかもしれません:さて、しかし、それは私が念頭に置いていたアニメーションではありません。問題ない!カスタムトランジションアーキテクチャに慣れたら、アニメーションを好きなように変更するのは簡単です。このバリアントでは、「古い」ビューコントローラがスライドしないように、1行コメントアウトしました。
だからあなたの想像力を暴走させましょう! iOSが意図する方法であるカスタム遷移アニメーションを採用します。
PushViewControllerナビゲーションに何か必要な場合は、これを試すことができます。
ただし、TabBarControllerでタブを切り替えると、これは機能しません。そのため、@mihai-erősのソリューションを使用します
スライドアニメーションの場合は、好みに応じてアニメーション期間を変更し、このクラスをナビゲーションセグエに割り当てます。
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)
})
}
}