iPhone : 애니메이션으로 탭을 전환하는 방법은 무엇입니까?
.NET을 사용하여 탭 모음 기반 응용 프로그램에서 프로그래밍 방식으로 탭을 전환하고 UITabBarController.selectedIndex
있습니다. 제가 해결하려는 문제는 뷰 간의 전환을 애니메이션으로 만드는 방법입니다. 즉. 현재 탭의보기에서 선택한 탭의보기로.
첫 번째 생각은를 사용하는 것이 UITabBarControllerDelegate
었지만 프로그래밍 방식으로 탭을 전환 할 때 호출되지 않는 것으로 보입니다. 나는 이제 UITabBarDelegate.didSelectItem
전환 애니메이션을 설정하는 가능한 후크로 :을 고려하고 있습니다.
누구든지 전환을 애니메이션으로 만들 수 있습니까? 그렇다면 어떻게?
2016 년 4 월 업데이트 : Justed는 모든 투표에 대해 모든 사람에게 감사의 말을 전하기 위해 이것을 업데이트하고 싶었습니다. 또한 이것은 원래 ARC 이전, 제약 이전, 이전 ... 많은 것들로 돌아가서 작성되었습니다! 따라서 이러한 기술을 사용할지 여부를 결정할 때이 점을 고려하십시오. 더 현대적인 접근 방식이있을 수 있습니다. 아, 그리고 찾으면. 모든 사람이 볼 수 있도록 응답을 추가하세요. 감사.
얼마 후 ...
많은 연구 끝에 두 가지 작업 솔루션을 찾았습니다. 둘 다 작동하고 탭 사이의 애니메이션을 수행했습니다.
솔루션 1 :보기에서 전환 (단순)
이것은 가장 쉽고 미리 정의 된 UIView 전환 방법을 사용합니다. 이 솔루션을 사용하면 방법이 우리를 위해 일하기 때문에 뷰를 관리 할 필요가 없습니다.
// Get views. controllerIndex is passed in as the controller we want to go to.
UIView * fromView = tabBarController.selectedViewController.view;
UIView * toView = [[tabBarController.viewControllers objectAtIndex:controllerIndex] view];
// Transition using a page curl.
[UIView transitionFromView:fromView
toView:toView
duration:0.5
options:(controllerIndex > tabBarController.selectedIndex ? UIViewAnimationOptionTransitionCurlUp : UIViewAnimationOptionTransitionCurlDown)
completion:^(BOOL finished) {
if (finished) {
tabBarController.selectedIndex = controllerIndex;
}
}];
해결 방법 2 : 스크롤 (더 복잡함)
더 복잡한 솔루션이지만 애니메이션을 더 많이 제어 할 수 있습니다. 이 예에서는 슬라이드를 켜고 끌 수있는 뷰를 얻습니다. 이것으로 우리는 뷰를 스스로 관리해야합니다.
// Get the views.
UIView * fromView = tabBarController.selectedViewController.view;
UIView * toView = [[tabBarController.viewControllers objectAtIndex:controllerIndex] view];
// Get the size of the view area.
CGRect viewSize = fromView.frame;
BOOL scrollRight = controllerIndex > tabBarController.selectedIndex;
// Add the to view to the tab bar view.
[fromView.superview addSubview:toView];
// Position it off screen.
toView.frame = CGRectMake((scrollRight ? 320 : -320), viewSize.origin.y, 320, viewSize.size.height);
[UIView animateWithDuration:0.3
animations: ^{
// Animate the views on and off the screen. This will appear to slide.
fromView.frame =CGRectMake((scrollRight ? -320 : 320), viewSize.origin.y, 320, viewSize.size.height);
toView.frame =CGRectMake(0, viewSize.origin.y, 320, viewSize.size.height);
}
completion:^(BOOL finished) {
if (finished) {
// Remove the old view from the tabbar view.
[fromView removeFromSuperview];
tabBarController.selectedIndex = controllerIndex;
}
}];
Swift의이 솔루션 :
extension TabViewController: UITabBarControllerDelegate {
public func tabBarController(tabBarController: UITabBarController, shouldSelectViewController viewController: UIViewController) -> Bool {
let fromView: UIView = tabBarController.selectedViewController!.view
let toView : UIView = viewController.view
if fromView == toView {
return false
}
UIView.transitionFromView(fromView, toView: toView, duration: 0.3, options: UIViewAnimationOptions.TransitionCrossDissolve) { (finished:Bool) in
}
return true
}
}
다음은 drekka 코드를 delegate (UITabBarControllerDelegate) 메서드에 사용하려는 시도입니다.
- (BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController {
NSArray *tabViewControllers = tabBarController.viewControllers;
UIView * fromView = tabBarController.selectedViewController.view;
UIView * toView = viewController.view;
if (fromView == toView)
return false;
NSUInteger fromIndex = [tabViewControllers indexOfObject:tabBarController.selectedViewController];
NSUInteger toIndex = [tabViewControllers indexOfObject:viewController];
[UIView transitionFromView:fromView
toView:toView
duration:0.3
options: toIndex > fromIndex ? UIViewAnimationOptionTransitionFlipFromLeft : UIViewAnimationOptionTransitionFlipFromRight
completion:^(BOOL finished) {
if (finished) {
tabBarController.selectedIndex = toIndex;
}
}];
return true;
}
iOS7.0 이상에 대한 내 솔루션입니다.
탭 모음의 대리자에서 사용자 지정 애니메이션 컨트롤러를 지정할 수 있습니다.
다음과 같은 애니메이션 컨트롤러를 구현합니다.
@interface TabSwitchAnimationController : NSObject <UIViewControllerAnimatedTransitioning>
@end
@implementation TabSwitchAnimationController
- (NSTimeInterval)transitionDuration:(id <UIViewControllerContextTransitioning>)transitionContext
{
return 0.2;
}
- (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext
{
UIViewController* fromVC = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
UIViewController* toVC = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
UIView* toView = toVC.view;
UIView* fromView = fromVC.view;
UIView* containerView = [transitionContext containerView];
[containerView addSubview:toView];
toView.frame = [transitionContext finalFrameForViewController:toVC];
// Animate by fading
toView.alpha = 0.0;
[UIView animateWithDuration:[self transitionDuration:transitionContext]
delay:0.0
options:UIViewAnimationOptionCurveEaseOut | UIViewAnimationOptionAllowUserInteraction
animations:^{
toView.alpha = 1.0;
}
completion:^(BOOL finished) {
toView.alpha = 1.0;
[fromView removeFromSuperview];
[transitionContext completeTransition:YES];
}];
}
@end
그런 다음 UITabBarControllerDelegate에서 사용하십시오.
- (id <UIViewControllerAnimatedTransitioning>)tabBarController:(UITabBarController *)tabBarController
animationControllerForTransitionFromViewController:(UIViewController *)fromVC
toViewController:(UIViewController *)toVC
{
return [[TabSwitchAnimationController alloc] init];
}
사용하는 대신 tabBarController:shouldSelectViewController:
구현 하는 것이 좋습니다tabBarController:animationControllerForTransitionFromViewController:toViewController:
TransitioningObject.swift
import UIKit
class TransitioningObject: NSObject, UIViewControllerAnimatedTransitioning {
func animateTransition(transitionContext: UIViewControllerContextTransitioning) {
let fromView: UIView = transitionContext.viewForKey(UITransitionContextFromViewKey)!
let toView: UIView = transitionContext.viewForKey(UITransitionContextToViewKey)!
transitionContext.containerView().addSubview(fromView)
transitionContext.containerView().addSubview(toView)
UIView.transitionFromView(fromView, toView: toView, duration: transitionDuration(transitionContext), options: UIViewAnimationOptions.TransitionCrossDissolve) { finished in
transitionContext.completeTransition(true)
}
}
func transitionDuration(transitionContext: UIViewControllerContextTransitioning) -> NSTimeInterval {
return 0.25
}
}
TabBarViewController.swift
import UIKit
class TabBarViewController: UITabBarController, UITabBarControllerDelegate {
override func viewDidLoad() {
super.viewDidLoad()
self.delegate = self
}
// MARK: - Tabbar delegate
func tabBarController(tabBarController: UITabBarController, animationControllerForTransitionFromViewController fromVC: UIViewController, toViewController toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? {
return TransitioningObject()
}
}
CATransition을 사용하여 UITabBarControlelr에 대한 전환을 쉽게 수행 할 수 있다고 생각합니다. 이것은 또한 transitionFromView : toView 사용의 모든 부작용을 해결합니다.
UITabBarController에서 확장 된 사용자 정의 TabBarController 클래스 내에서 이것을 사용하십시오.
- (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController (UIViewController*)viewController {
CATransition *animation = [CATransition animation];
[animation setType:kCATransitionFade];
[animation setDuration:0.25];
[animation setTimingFunction:[CAMediaTimingFunction functionWithName:
kCAMediaTimingFunctionEaseIn]];
[self.view.window.layer addAnimation:animation forKey:@"fadeTransition"];
}
도움이 되었기를 바랍니다 :)
내가 쓴 글을 여기에 다양한 답변을 시도한 후.
코드는 Swift에 있으며을 호출하여 애니메이션으로 탭을 프로그래밍 방식으로 변경할 수 있습니다 animateToTab
.
func animateToTab(toIndex: Int) {
let tabViewControllers = viewControllers!
let fromView = selectedViewController!.view
let toView = tabViewControllers[toIndex].view
let fromIndex = tabViewControllers.indexOf(selectedViewController!)
guard 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.mainScreen().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.userInteractionEnabled = false
UIView.animateWithDuration(0.5, delay: 0.0, usingSpringWithDamping: 1, initialSpringVelocity: 0, options: UIViewAnimationOptions.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.userInteractionEnabled = true
})
}
모든 탭 변경에 애니메이션이 포함되도록하려면 다음 UITabBarControllerDelegate
과 같이 연결합니다 .
func tabBarController(tabBarController: UITabBarController, shouldSelectViewController viewController: UIViewController) -> Bool {
let tabViewControllers = tabBarController.viewControllers!
guard let toIndex = tabViewControllers.indexOf(viewController) else {
return false
}
// Our method
animateToTab(toIndex)
return true
}
Swift의 내 솔루션 :
사용자 지정 TabBar 클래스를 만들고 스토리 보드 TabBar에서 설정합니다.
class MainTabBarController: UITabBarController, UITabBarControllerDelegate {
override func viewDidLoad() {
super.viewDidLoad()
self.delegate = self
// Do any additional setup after loading the view.
}
func tabBarController(tabBarController: UITabBarController, shouldSelectViewController viewController: UIViewController) -> Bool {
let tabViewControllers = tabBarController.viewControllers!
let fromView = tabBarController.selectedViewController!.view
let toView = viewController.view
if (fromView == toView) {
return false
}
let fromIndex = tabViewControllers.indexOf(tabBarController.selectedViewController!)
let toIndex = tabViewControllers.indexOf(viewController)
let offScreenRight = CGAffineTransformMakeTranslation(toView.frame.width, 0)
let offScreenLeft = CGAffineTransformMakeTranslation(-toView.frame.width, 0)
// start the toView to the right of the screen
if (toIndex < fromIndex) {
toView.transform = offScreenLeft
fromView.transform = offScreenRight
} else {
toView.transform = offScreenRight
fromView.transform = offScreenLeft
}
fromView.tag = 124
toView.addSubview(fromView)
self.view.userInteractionEnabled = false
UIView.animateWithDuration(0.5, delay: 0.0, usingSpringWithDamping: 1, initialSpringVelocity: 0, options: UIViewAnimationOptions.CurveEaseOut, animations: {
toView.transform = CGAffineTransformIdentity
}, completion: { finished in
let subViews = toView.subviews
for subview in subViews{
if (subview.tag == 124) {
subview.removeFromSuperview()
}
}
tabBarController.selectedIndex = toIndex!
self.view.userInteractionEnabled = true
})
return true
}
}
@Mofumofu의 솔루션을 사용하여 Swift 1.2로 업그레이드하고 업 / 다운 애니메이션도 구현했습니다. 의미, 새로운 ViewController가 나타나고 새로운 viewcontroller의 인덱스가 이전의 것보다 크면 이전의 것을 푸시합니다. 그렇지 않으면 방향이 아래입니다.
class TabScrollPageAnimationController: NSObject, UIViewControllerAnimatedTransitioning {
let tabBarController: UITabBarController
init(tabBarController: UITabBarController) {
self.tabBarController = tabBarController
}
func transitionDuration(transitionContext: UIViewControllerContextTransitioning) -> NSTimeInterval {
return 0.5
}
func animateTransition(transitionContext: UIViewControllerContextTransitioning) {
if let fromVC = transitionContext.viewControllerForKey(UITransitionContextFromViewControllerKey),
let toVC = transitionContext.viewControllerForKey(UITransitionContextToViewControllerKey) {
let fromView = fromVC.view
let toView = toVC.view
let containerView = transitionContext.containerView()
var directionUpwardMultiplier: CGFloat = 1.0
if let vcs = tabBarController.viewControllers as? [UIViewController],
let fIndex = find(vcs, fromVC),
let tIndex = find(vcs, toVC) {
directionUpwardMultiplier = (fIndex < tIndex) ? +1.0 : -1.0
}
containerView.clipsToBounds = false
containerView.addSubview(toView)
var fromViewEndFrame = fromView.frame
fromViewEndFrame.origin.y -= (containerView.frame.height * directionUpwardMultiplier)
let toViewEndFrame = transitionContext.finalFrameForViewController(toVC)
var toViewStartFrame = toViewEndFrame
toViewStartFrame.origin.y += (containerView.frame.height * directionUpwardMultiplier)
toView.frame = toViewStartFrame
toView.alpha = 0.0
UIView.animateWithDuration(transitionDuration(transitionContext), delay: 0.0, usingSpringWithDamping: 1.0, initialSpringVelocity: 0.0, options: UIViewAnimationOptions.CurveEaseInOut, animations: { () -> Void in
toView.alpha = 1.0
toView.frame = toViewEndFrame
fromView.alpha = 0.0
fromView.frame = fromViewEndFrame
}, completion: { (completed) -> Void in
toView.alpha = 1.0
fromView.removeFromSuperview()
transitionContext.completeTransition(completed)
containerView.clipsToBounds = true
})
}
}
}
컨테이너 ViewController에서 :
extension XYViewController: UITabBarControllerDelegate {
func tabBarController(tabBarController: UITabBarController, animationControllerForTransitionFromViewController fromVC: UIViewController, toViewController toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? {
return TabScrollPageAnimationController(tabBarController: tabBarController)
}
}
내 Swift 3 솔루션은 다음과 같습니다.
내 UITabBarViewController의 selectedIndex를 다음과 같이 재정의합니다.
override var selectedIndex: Int{
get{
return super.selectedIndex
}
set{
animateToTab(toIndex: newValue)
super.selectedIndex = newValue
}
}
그런 다음 기본 푸시 / 팝 애니메이션을 모방 한이 함수를 사용합니다.
func animateToTab(toIndex: Int) {
guard let tabViewControllers = viewControllers, tabViewControllers.count > toIndex, let fromViewController = selectedViewController, let fromIndex = tabViewControllers.index(of: fromViewController), fromIndex != toIndex else {return}
view.isUserInteractionEnabled = false
let toViewController = tabViewControllers[toIndex]
let push = toIndex > fromIndex
let bounds = UIScreen.main.bounds
let offScreenCenter = CGPoint(x: fromViewController.view.center.x + bounds.width, y: toViewController.view.center.y)
let partiallyOffCenter = CGPoint(x: fromViewController.view.center.x - bounds.width*0.25, y: fromViewController.view.center.y)
if push{
fromViewController.view.superview?.addSubview(toViewController.view)
toViewController.view.center = offScreenCenter
}else{
fromViewController.view.superview?.insertSubview(toViewController.view, belowSubview: fromViewController.view)
toViewController.view.center = partiallyOffCenter
}
UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 0, options: .curveEaseIn, animations: {
toViewController.view.center = fromViewController.view.center
fromViewController.view.center = push ? partiallyOffCenter : offScreenCenter
}, completion: { finished in
fromViewController.view.removeFromSuperview()
self.view.isUserInteractionEnabled = true
})
}
나는 그것이 도움이되기를 바랍니다 :)
불안전 한 애니메이션 수정 ...
UIView * fromView = self.view.superview;
이것은 두 가지 방법으로 해결할 수 있습니다
1-AppDelegate.m 파일에 한 번 작성하십시오. AppDelegate.h에서 콜론 (:) 뒤에 <>를 사용하여 UITabBarControllerDelegate를 포함해야합니다.
-(void)tabBarController:(UITabBarController *)tabBarControllerThis didSelectViewController:(UIViewController *)viewController
{
[UIView transitionWithView:viewController.view
duration:0.1
options:UIViewAnimationOptionAllowUserInteraction | UIViewAnimationOptionTransitionCrossDissolve
animations:^(void){
} completion:^(BOOL finished){
[UIView beginAnimations:@"animation" context:nil];
[UIView setAnimationDuration:0.7];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft
forView:viewController.view
cache:NO];
[UIView commitAnimations];
}];
}
2-각 ViewController.m 파일에 작성하십시오.
-(void)viewWillAppear:(BOOL)animated
{
[UIView transitionWithView:self.view
duration:1.0
options:UIViewAnimationOptionAllowUserInteraction | UIViewAnimationOptionTransitionCrossDissolve
animations:^(void){
[super viewWillAppear:YES];
} completion:^(BOOL finished){
}];
}
이 도움을 바랍니다 ...!
탭한 항목에 따라 애니메이션 할 수 있습니다.이 예에서는 탭한 색인이 이전에 선택한 색인보다>이면 flipFromLeft를, 탭한 색인이 이전에 선택한 색인보다 작 으면 flipFromRight를 플립합니다. 이것은 Swift 4입니다 : UITabBarControllerDelegate 메소드 구현
func tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) -> Bool {
let fromView: UIView = tabBarController.selectedViewController!.view
let toView: UIView = viewController.view
if fromView == toView {
return false
}
if let tappedIndex = tabBarController.viewControllers?.index(of: viewController) {
if tappedIndex > tabBarController.selectedIndex {
UIView.transition(from: fromView, to: toView, duration: 0.5, options: UIViewAnimationOptions.transitionFlipFromLeft, completion: nil)
} else {
UIView.transition(from: fromView, to: toView, duration: 0.5, options: UIViewAnimationOptions.transitionFlipFromRight, completion: nil)
}
}
return true
}
drekka의 대답은 정말 좋습니다. 스크롤 전환을 약간 조정하여 애니메이션이 Apple의 푸시 애니메이션처럼 보이도록했습니다. 첫 번째 애니메이션이 완료되면 추가 애니메이션을 추가하여 해당 슬라이딩 효과가 제대로 보이도록했습니다.
// Disable interaction during animation to avoids bugs.
self.tabBarController.view.userInteractionEnabled = NO;
// Get the views.
UIView * fromView = tabBarController.selectedViewController.view;
UIView * toView = [[tabBarController.viewControllers objectAtIndex:controllerIndex] view];
// Get the size of the view area.
CGRect viewSize = fromView.frame;
BOOL scrollRight = controllerIndex > tabBarController.selectedIndex;
// Add the to view to the tab bar view.
[fromView.superview addSubview:toView];
[fromView.superview addSubview:fromView];
self.tabBarController.selectedIndex = 0;
// Position it off screen.
toView.frame = CGRectMake((scrollRight ? (viewSize.size.width *.25) : -(viewSize.size.width * .25 )), viewSize.origin.y, viewSize.size.width, viewSize.size.height);
[UIView animateWithDuration:0.25
animations: ^{
// Animate the views on and off the screen.
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
fromView.frame = CGRectMake(viewSize.size.width * .95, viewSize.origin.y, viewSize.size.width, viewSize.size.height);
toView.frame = CGRectMake((viewSize.origin.x * .90), viewSize.origin.y, viewSize.size.width, viewSize.size.height);
}
completion:^(BOOL finished) {
if (finished) {
// Being new animation.
[UIView animateWithDuration:0.2
animations: ^{
[UIView setAnimationCurve:UIViewAnimationCurveLinear];
fromView.frame = CGRectMake(viewSize.size.width, viewSize.origin.y, viewSize.size.width, viewSize.size.height);
toView.frame = CGRectMake((viewSize.origin.x), viewSize.origin.y, viewSize.size.width, viewSize.size.height);
}
completion:^(BOOL finished) {
if (finished) {
// Remove the old view from the tabbar view.
[fromView removeFromSuperview];
// Restore interaction.
self.tabBarController.view.userInteractionEnabled = YES;
}
}];
}
}];
버튼을 누를 때 두 개의 자식 뷰 컨트롤러간에 플립 전환을 사용하고 싶었고 다음과 같이 달성했습니다.
-(IBAction)flipViewControllers:(id)sender{
NSUInteger index = self.selectedIndex;
index++;
if(index >= self.childViewControllers.count){
index = 0;
}
self.selectedIndex = index;
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.75];
[UIView setAnimationTransition:index % 2 ? UIViewAnimationTransitionFlipFromLeft : UIViewAnimationTransitionFlipFromRight
forView:self.view
cache:YES];
[UIView commitAnimations];
}
또한 배경색을 검정색으로 설정했습니다. 제 경우에는 navigationController.view.backgroundColor를 설정하여 수행했지만 귀하의 경우에는 앱 델리게이트에서 쉽게 설정할 수있는 window.backgroundColor 일 수 있습니다.
다음 은 탭 간의 전환을 애니메이션으로 만드는 작업 코드입니다 ( 3 개의 탭 에 대해 더 이상 시도하지 않았습니다 !!). 주로 drekka의 솔루션을 기반으로하지만 이미 탭바의 델리게이트 메서드에 구현되어 있으므로 복사 / 붙여 넣기 만하면 작업을 수행해야합니다.
-(BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController {
// Important! We validate that the selected tab is not the current tab, to avoid misplacing views
if (tabBarController.selectedViewController == viewController) {
return NO;
}
// Find the selected view's index
NSUInteger controllerIndex = 0;
for (UIViewController *vc in tabBarController.viewControllers) {
if (vc == viewController) {
controllerIndex = [tabBarController.viewControllers indexOfObject:vc];
}
}
CGFloat screenWidth = SCREEN_SIZE.width;
// Note: We must invert the views according to the direction of the scrolling ( FROM Left TO right or FROM right TO left )
UIView * fromView = tabBarController.selectedViewController.view;
UIView * toView = viewController.view;
[fromView.superview addSubview:toView];
CGRect fromViewInitialFrame = fromView.frame;
CGRect fromViewNewframe = fromView.frame;
CGRect toViewInitialFrame = toView.frame;
if ( controllerIndex > tabBarController.selectedIndex ) {
// FROM left TO right ( tab0 to tab1 or tab2 )
// The final frame for the current view. It will be displaced to the left
fromViewNewframe.origin.x = -screenWidth;
// The initial frame for the new view. It will be displaced to the left
toViewInitialFrame.origin.x = screenWidth;
toView.frame = toViewInitialFrame;
} else {
// FROM right TO left ( tab2 to tab1 or tab0 )
// The final frame for the current view. It will be displaced to the right
fromViewNewframe.origin.x = screenWidth;
// The initial frame for the new view. It will be displaced to the right
toViewInitialFrame.origin.x = -screenWidth;
toView.frame = toViewInitialFrame;
}
[UIView animateWithDuration:0.2 animations:^{
// The new view will be placed where the initial view was placed
toView.frame = fromViewInitialFrame;
// The initial view will be place outside the screen bounds
fromView.frame = fromViewNewframe;
tabBarController.selectedIndex = controllerIndex;
// To prevent user interaction during the animation
[[UIApplication sharedApplication] beginIgnoringInteractionEvents];
} completion:^(BOOL finished) {
// Before removing the initial view, we adjust its frame to avoid visual lags
fromView.frame = CGRectMake(0, 0, fromView.frame.size.width, fromView.frame.size.height);
[fromView removeFromSuperview];
[[UIApplication sharedApplication] endIgnoringInteractionEvents];
}];
return NO;
}
이것은 Swift 3에서 저에게 효과적입니다.
func tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) -> Bool {
if let fromView = tabBarController.selectedViewController?.view, let toView = viewController.view {
if fromView == toView {
return false
}
UIView.transition(from: fromView, to: toView, duration: 0.2, options: .transitionCrossDissolve) { (finished) in
}
}
return true
}
@samwize 답변이 Swift 3-2 개의 엄지 손가락으로 번역되어 왼쪽에서 라이트 페이지 효과를 만듭니다.
func animateToTab(toIndex: Int) {
let tabViewControllers = viewControllers!
let fromView = selectedViewController!.view
let toView = tabViewControllers[toIndex].view
let fromIndex = tabViewControllers.index(of: selectedViewController!)
guard 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 = screenSize.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.5, delay: 0.0, usingSpringWithDamping: 1, initialSpringVelocity: 0, options: UIViewAnimationOptions.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
})
}
@samwize의 답변 이 Swift 5로 업데이트되었습니다.
모든 탭 변경에 애니메이션이 포함되도록하려면 UITabBarControllerDelegate를 사용하고 다음 메서드를 구현합니다.
func tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) -> Bool {
let tabViewControllers = tabBarController.viewControllers!
guard let toIndex = tabViewControllers.indexOf(value:viewController) else {
return false
}
animateToTab(toIndex: toIndex, fadeOutFromView: false, fadeInToView: false)
return true
}
다음을 호출하여 애니메이션으로 탭을 프로그래밍 방식으로 변경합니다 animateToTab
.
func animateToTab(toIndex: Int, fadeOutFromView: Bool, fadeInToView: Bool) {
let tabViewControllers = viewControllers!
let fromView = selectedViewController!.view
let toView = tabViewControllers[toIndex].view
let fromIndex = tabViewControllers.indexOf(value:selectedViewController!)
guard 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.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
if fadeInToView {
toView!.alpha = 0.1
}
UIView.animate(withDuration: 0.5, delay: 0.0, usingSpringWithDamping: 1, initialSpringVelocity: 0, options: [.curveEaseOut], animations: {
if fadeOutFromView {
fromView!.alpha = 0.0
}
if fadeInToView {
toView!.alpha = 1.0
}
// 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
})
}
Swift 4+
당신이 UITabBarControllerDelegate
방법은 다음과 같이해야한다
func tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) -> Bool {
animateToTab(toIndex: (tabBarController.viewControllers?.index(of: viewController))!)
return true
}
그리고 방법은,
func animateToTab(toIndex: Int) {
let tabViewControllers = viewControllers!
let fromView = selectedViewController!.view
let toView = tabViewControllers[toIndex].view
let fromIndex = tabViewControllers.index(of: selectedViewController!)
guard 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.5, delay: 0.0, usingSpringWithDamping: 1, initialSpringVelocity: 0, options: UIViewAnimationOptions.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
});
}
참고 URL : https://stackoverflow.com/questions/5161730/iphone-how-to-switch-tabs-with-an-animation
'IT story' 카테고리의 다른 글
파이썬 목록은 얼마나 커질 수 있습니까? (0) | 2020.08.09 |
---|---|
Eclipse 보안 스토리지 (0) | 2020.08.09 |
ECMAScript 란 무엇입니까? (0) | 2020.08.09 |
Ruby에서“===”연산자는 무엇을합니까? (0) | 2020.08.09 |
XX.XXX.XX.XX와 (과) 협상 할 수 없습니다. 일치하는 호스트 키 유형이 없습니다. (0) | 2020.08.09 |