আইফোন: অ্যানিমেশন দিয়ে কীভাবে ট্যাবগুলি স্যুইচ করবেন?


106

আমি একটি ট্যাব বার চালিত অ্যাপ্লিকেশন ব্যবহার করে প্রোগ্রামগুলিতে ট্যাবগুলি স্যুইচ করছি UITabBarController.selectedIndex। আমি যে সমস্যাটি সমাধান করার চেষ্টা করছি তা হ'ল ভিউগুলির মধ্যে রূপান্তর কীভাবে সক্রিয় করা যায়। অর্থাত। বর্তমান ট্যাবটির ভিউ থেকে নির্বাচিত ট্যাবটির দর্শন।

প্রথম চিন্তাটি ব্যবহার করার কথা ছিল UITabBarControllerDelegate, তবে এটি প্রদর্শিত হয় যে প্রোগ্রামগুলি ট্যাবগুলি স্যুইচ করার সময় এটি বলা হয় না। আমি এখন বিবেচনা করছি UITabBarDelegate.didSelectItem: একটি রূপান্তর অ্যানিমেশন সেট করার একটি সম্ভাব্য হুক হিসাবে।

ট্রানজিশনগুলি অ্যানিমেটেড করতে কেউ কি পরিচালিত হয়েছে? যদি হ্যাঁ, কিভাবে?


1
এফডব্লিউআইডাব্লু, এর মধ্যে অনেকগুলি উচ্চ ভোট দেওয়া উত্তরগুলি রুনোর উত্তর এবং হেবার্টির ক্ষেত্রেও বর্ণিত কাস্টম ট্রানজিশনগুলির পূর্বনির্ধারিত । এই কাস্টম অ্যানিমেশনগুলি সামলানোর সঠিক উপায়। WWDC দেখুন 2013 ভিডিও কাস্টম স্থানান্তর দেখুন কন্ট্রোলার ব্যবহার
রব

উত্তর:


154

আপডেট ০৪/২০১6: সকল ভোটের জন্য প্রত্যেককে আপনাকে ধন্যবাদ জানাতে জাস্ট এই আপডেট করতে চেয়েছিলেন। দয়া করে নোট করুন যে এটি যখন মূলত ফিরে লেখা হয়েছিল তখন ... আর সি এর আগে, সীমাবদ্ধতার আগে, আগে ... প্রচুর স্টাফ! সুতরাং এই কৌশলগুলি ব্যবহার করবেন কিনা তা সিদ্ধান্ত নেওয়ার সময় দয়া করে এটিকে ધ્યાનમાં রাখুন। আরও আধুনিক পদ্ধতির হতে পারে। ওহ, এবং যদি আপনি একটি খুঁজে। দয়া করে একটি প্রতিক্রিয়া যুক্ত করুন যাতে প্রত্যেকে দেখতে পায়। ধন্যবাদ।

একটু পরে ...

অনেক গবেষণার পরে আমি দুটি কার্যনির্বাহী সমাধান নিয়ে এসেছি। এই উভয়ই ট্যাবগুলির মধ্যে অ্যানিমেশন কাজ করেছে এবং করেছে।

সমাধান 1: দর্শন থেকে রূপান্তর (সহজ)

এটি সবচেয়ে সহজ এবং একটি পূর্বনির্ধারিত ইউআইভিউভিউ রূপান্তর পদ্ধতি ব্যবহার করে। এই সমাধানের সাথে আমাদের মতামতগুলি পরিচালনা করার দরকার নেই কারণ পদ্ধতিটি আমাদের পক্ষে কাজ করে।

// 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;                
                     }
                 }];

সুইফটে এই সমাধান:

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
   }
}

1
উত্তরের জন্য অনেক ধন্যবাদ, এটি সত্যই ভাল কাজ করে। তবে আমি উভয় সমাধানে একটি ত্রুটি পেয়েছি, আমি নিশ্চিত নই যে এটি সবার সাথে ঘটেছিল কিনা, তবে মনে হয় পৃষ্ঠাটি রূপান্তরিত হলে নেভিগেশন বার এবং স্ট্যাটাস বারের মধ্যে ফাঁক থাকে, তারপরে অ্যানিমেশন শেষ হওয়ার পরে, ফাঁক বন্ধ এটি অ্যানিমেশনটির সমাপ্তিটিকে কিছুটা বিড়বিড় করে তোলে। কেন এমন হচ্ছে জানো?
এনরিকো সুস্যাতিयो

হুম, আমার কোড নিয়ে হচ্ছিল না। এটি এমন একটি সমস্যার মতো শোনায় যা আমি এর আগে দেখেছি যেখানে উইন্ডো এবং স্থিতি বারের সাথে সম্পর্কিত নতুন ভিউ ফ্রেমের অবস্থান সঠিক নয়। কোনও রূপান্তর না করে দেখুন অদলবদল করতে টো কোড চালানোর চেষ্টা করুন এবং দেখুন এটি এখনও ঘটে কিনা।
ড্রেক্কা

হ্যাঁ, এটি কোনও রূপান্তর না করেই ঘটে। আমি প্রথম পদ্ধতি চেষ্টা করেছিলাম। এটি ফ্রেমের অবস্থান হতে পারে, আমি এটির সাথে আরও কিছুটা খেলব। আমি ফ্রেমটি উপরে স্থানান্তরিত করার চেষ্টা করেছি, এবং ভিউয়ের সাথে ফ্রেমের সাথে মিলের চেষ্টা করেছি তবে এখনও ভাগ্য নেই ...
এনরিকো সুস্যাতিও

2
@ এমিলিক কোরমিয়ার এটি ট্যাববারের প্রতিনিধি shouldSelectViewControllerপদ্ধতিতে রাখুন এবং সেখানে আর ফিরে আসবেন না
চিজুস

2
@ ড্রেক্কা এটি আমার পক্ষে কাজ করছে না। আপনি কি ব্যাখ্যা করতে পারেন যে কন্ট্রোলার ইন্ডেক্স থেকে এসেছে? এবং আপনি কেন 'টু ভিউ'র জন্য ট্যাববারকন্ট্রোলারডেলিগেট পদ্ধতি থেকে [ভিউকন্ট্রোলার ভিউ] ব্যবহার করছেন না? থ্যাঙ্কস
শানোগোগ

25

ডেলিগেট (ইউআইটিববারকন্ট্রোলারডেলিগেট) পদ্ধতিতে কোড ফর্ম ড্রেকা ব্যবহার করার জন্য আমার চেষ্টাটি নিম্নলিখিত

- (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;
}

2
পদ্ধতির ঘোষণাপত্র অনুসারে আপনার কিছুটা মূল্য ফেরত দেওয়া উচিত তবে এই পদ্ধতিটি +1
ভোরোম্যাক্স

2
আপনি নিজের UITabController বাস্তবায়ন ফাইলে স্ব.ডিলেগেট = স্ব যোগ করে প্রতিনিধি সেট করতে পারেন; আপনার ভিউডিডলোড () ফাংশনে। এটি উপরের ফাংশনটি কল করার অনুমতি দেবে।
ক্রিস ফ্রেমজেন

21

আইওএস 7.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

তারপরে এটি আপনার ইউআইটিববারকন্ট্রোলারডেলিগেটে ব্যবহার করুন:

- (id <UIViewControllerAnimatedTransitioning>)tabBarController:(UITabBarController *)tabBarController
            animationControllerForTransitionFromViewController:(UIViewController *)fromVC
                                              toViewController:(UIViewController *)toVC
{
    return [[TabSwitchAnimationController alloc] init];
}

2
এবং মনে রাখবেন যে আপনার ডেলিগেটটি ট্যাবভিউ কনট্রোলারের ডেলিগেট আউটলেটে জড়িত। সুন্দর কাজ করেছেন। এখানে সবচেয়ে পরিষ্কার সমাধান।
অ্যান্ড্রু ডানকান

স্টোরিবোর্ডের মাধ্যমে এটি কি এখনই দ্রুত করা যায় যে আমি আইওএস 10.x এ এই বৈশিষ্ট্যটি দেখছি?
মুবিবব

16

ব্যবহারের পরিবর্তে 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()
    }
}

3
এটি সেরা উত্তর বলে মনে হচ্ছে। এই সমাধানে কোনও সমস্যা নেই।
সাবিল্যান্ড

15

আমি মনে করি আপনি সহজেই ক্যাটাট্রিশন ব্যবহার করে ইউআইটিববারকন্ট্রোলারের জন্য রূপান্তরগুলি অর্জন করতে পারবেন; এটি ট্রানজিশনফর্মভিউ: টু ভিউ: ব্যবহারের যে কোনও পার্শ্ব প্রতিক্রিয়াও সমাধান করবে

এটি আপনার কাস্টম ট্যাববারকন্ট্রোলার শ্রেণীর ভিতরে ইউআইটিববারকন্ট্রোলার থেকে বর্ধিত করুন।

- (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"];
}

আশাকরি এটা সাহায্য করবে :)


1
আমি মনে করি আমরা "didSelectViewController" এর পরিবর্তে "shouldSelectViewController" ব্যবহার করতে পারি
রায়ান উ

13

আমি এখানে বিভিন্ন উত্তর চেষ্টা করার পরে একটি পোস্ট লিখেছি ।

কোডটি সুইফটে রয়েছে, এবং আপনি কল করে প্রোগ্রামটিমে অ্যানিমেশন সহ ট্যাবটি পরিবর্তন করতে পারবেন 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
}

এটি খুব পরিষ্কার এবং সুন্দরভাবে অ্যানিমেট করে।
মোহাম্মদ জেকরুল্লাহ

9

সুইফটে আমার সমাধান:

কাস্টম ট্যাববার ক্লাস তৈরি করুন এবং এটি আপনার স্টোরিবোর্ড ট্যাববারে সেট করুন

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
 }

}

এটি আইওএস 9 এ কাজ করছে না - অনুসন্ধান পদ্ধতি থেকে ত্রুটি ফিরে এসেছে অর্থাৎ '[ইউআইভিউকন্ট্রোলার] থেকে ডাউনকাস্ট?' '[ইউআইভিউউকন্ট্রোলার]' কেবলমাত্র বিকল্পগুলি আন-র্যাপ করে; আপনার ব্যবহারের অর্থ '!'?
লজফ্লান

এটি প্রায় ভাল ছিল, আমি এমন একটি বাগের মুখোমুখি হয়েছি যা অ্যানিমেট করবে না ( finishedমিথ্যা হবে)। কেন হয় তা আমি জানি না, তবে আমি মনে করি এটি সিএ রূপান্তরকরণের সাথে হয়েছে যা মনে করে যে "অ্যানিমেটেড করার কিছুই নেই" nothing আমি ফ্রেমগুলির সাথে অ্যানিমেটিংয়ে স্যুইচ করেছি, এবং এটি কার্যকর।
সমেয় করুন

3

আমি @ মফুমোফুর সমাধানটি ব্যবহার করেছি এবং এটিকে সুইফট ১.২ এ আপগ্রেড করেছি এবং একটি আপ / ডাউন অ্যানিমেশনটিও প্রয়োগ করেছি। অর্থ, নতুন ভিউ কন্ট্রোলারটি উঠে আসে এবং পুরানোটিকে ধাক্কা দেয় যদি নতুন ভিউকন্ট্রোলারের সূচকটি পুরানোটির চেয়ে বেশি হয়। নইলে দিক নিচে থাকে।

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
                })

        }
    }

}

ধারক ভিউ কন্ট্রোলারে:

extension XYViewController: UITabBarControllerDelegate {

    func tabBarController(tabBarController: UITabBarController, animationControllerForTransitionFromViewController fromVC: UIViewController, toViewController toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? {
        return TabScrollPageAnimationController(tabBarController: tabBarController)
    }

}

3

এখানে আমার সুইফট 3 সমাধান:

আমি আমার ইউআইটিববারভিউউকন্ট্রোলার এর নির্বাচিত ইনডেক্সকে ওভাররাইড করি:

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
    })
}

আমি আসা করি এটা সাহায্য করবে :)


2

দুরন্ত অ্যানিমেশন জন্য একটি স্থির ...

UIView * fromView = self.view.superview;


2

এটি দুটি উপায়ে সমাধান করা যেতে পারে

1 - এটি একবার আপনার AppDelegate.m ফাইলে লিখুন। আপনার অ্যাপডেলিগেটে কোলনের পরে <> ব্যবহার করে 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 - আপনার প্রতিটি ভিউকন্ট্রোলআরএম ফাইলটিতে এটি লিখুন

-(void)viewWillAppear:(BOOL)animated
{
    [UIView transitionWithView:self.view
                      duration:1.0
                       options:UIViewAnimationOptionAllowUserInteraction | UIViewAnimationOptionTransitionCrossDissolve
                    animations:^(void){
                        [super viewWillAppear:YES];
                    } completion:^(BOOL finished){
                    }];
}

এই সাহায্য আশা করি ...!


1
আমি কীভাবে নেভিগেশন কন্ট্রোলারগুলির মধ্যে স্থানান্তরের অ্যানিমেট করতে পারি? ট্যাববারকন্ট্রোলারডেলিগেটটি কেবলমাত্র নিয়ন্ত্রণ নিয়ন্ত্রণকারীর সাথে কাজ করে।
saeppi

আমি উভয়ই চেষ্টা করেছিলাম, প্রথমটি নতুন দৃষ্টিভঙ্গি প্রদর্শন করেছে এবং এটি অ্যানিমেটেডের চেয়ে যা দেখতে দেখতে বিশ্রী দেখাচ্ছে। দ্বিতীয়টির কোনও প্রভাব আছে বলে মনে হয় না। আমি ট্যাব 2 এর সাথে যুক্ত ভিউতে গিয়ে ভিউইলঅ্যাপিয়ার কোডটিতে কোডটি যুক্ত করে এটি পরীক্ষা করেছি এবং ট্যাবগুলির মধ্যে কোনও দৃশ্যমান অ্যানিমেশন নেই।
শ্যানন কোল

এটির জন্য ডিফল্ট এক্সকোড ট্যাববারকন্ট্রোলার প্রকল্পটি ব্যবহার করে দেখুন। 1 বা 2 এর সাথে ভাগ্য নেই আমি সত্যিই তাদের কাজ করতে চেয়েছিলাম। :) আমি কি কিছু মিস করছি?
অ্যান্ড্রু ডানকান

আমিও, ভাগ্য নেই .. কোন ধারণা?
জন

2

আপনি আলতো চাপানো আইটেমের উপর নির্ভর করে অ্যানিমেট করতে পারেন - এই উদাহরণে আমরা উল্লিখিত সূচকটি পূর্ববর্তী নির্বাচিত সূচকের তুলনায়> যদি ফ্লিপফ্রমফিট করি এবং আমরা যদি নির্বাচিত সূচকটি পূর্ববর্তী নির্বাচিত সূচকের তুলনায় <হয় তবে আমরা ফ্লিপফ্র্যামরাইটে ফ্লপ করব। এটি সুইফট 4: ইউআইটিববারকন্ট্রোলারডেলিগেট পদ্ধতিটি প্রয়োগ করুন

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
}

এটি কাজ করছে না। আমি এটিকে দৃশ্যের নিয়ামক হিসাবে প্রয়োগ করেছি
দেদেভ

@ দেদেভ এই সমাধান নিয়ে কী কাজ করছেন না? আপনি কি নিজের ভিউকন্ট্রোলারে ইউআইটিববারকন্ট্রোলারডেলিগেট সেট করেছেন?
তেটজ

হ্যাঁ, আমি অ্যাপ্লিকেশন ক্লাসের অ্যাপডেলিগেটে নিম্নলিখিতটি করেছি: ইউআইআরআইএসপন্ডার, ইউআইএপ্লিকেশনডেলিগেট, ইউআইটিববারকন্ট্রোলারডেলিগেট {}} আমি দ্রুত এসেছি আপনি কি আপনার উত্তর প্লিজের ধাপগুলি বিস্তারিত বর্ণনা করতে পারেন?
দেবেদভ

@ দেবদেব যদি এটি হয় আপনার অ্যাপডিলেগেট ক্লাসটি আপনার অ্যাপলিজেটে উপরে ফাংশনটি রাখে এবং কাজ করা উচিত
তেটজ


1

ড্রেক্কার উত্তরটি সত্যিই দুর্দান্ত। আমি অল্প অল্প অল্প অল্প পরিমাণে স্ক্রোল স্থানান্তর করেছি যাতে অ্যানিমেশনটি অ্যাপলের ধাক্কা অ্যানিমেশনের মতো দেখায়। স্লাইডিং এফেক্টটি সঠিক দেখতে পেতে আমি প্রথম অ্যানিমেশনটি সম্পূর্ণ হওয়ার পরে একটি অতিরিক্ত অ্যানিমেশন যুক্ত করেছি।

// 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;
                                              }
                                          }];
                 }
             }];

0

আমি একটি বাটন টিপে দু'জন চাইল্ড ভিউ কন্ট্রোলারের মধ্যে ফ্লিপ ট্রানজিশনটি ব্যবহার করতে চেয়েছিলাম এবং এটি নিম্নলিখিত হিসাবে অর্জন করেছি:

-(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];
}

আমি ব্যাকগ্রাউন্ডের রঙটিও কালোতে সেট করেছিলাম, আমার ক্ষেত্রে আমি নেভিগেশনকন্ট্রোলআরভিউ.ব্যাকগ্রাউন্ড কালার সেট করে এটি করেছি তবে আপনার ক্ষেত্রে এটি উইন্ডো.ব্যাকগ্রাউন্ড কালার হতে পারে যা অ্যাপ্লিকেশন প্রতিনিধিতে সহজেই সেট করা যায়।


0

ট্যাবগুলির মধ্যে রূপান্তর সঞ্চার করার জন্য এখানে আমার ওয়ার্কিং কোড ( 3 টি ট্যাবগুলির জন্য , এটির চেয়ে বেশি চেষ্টা করে দেখেনি !!)। এটি মূলত ড্রেক্কার সমাধানের উপর ভিত্তি করে, তবে ইতিমধ্যে ট্যাববারের প্রতিনিধি পদ্ধতিতে প্রয়োগ করা হয়েছে, সুতরাং আপনি যদি কেবল এটি অনুলিপি / পেস্ট করেন তবে কাজটি করা উচিত .. (আপনি কখনই জানেন না!)

-(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;

}


এই কোড স্নিপেট একটি ব্যাখ্যা সহ প্রশ্নটি সমাধান করতে পারে, যদিও সত্যিই আপনার পোস্টের মান উন্নত করতে সহায়তা করে। মনে রাখবেন যে আপনি ভবিষ্যতে পাঠকদের জন্য প্রশ্নের উত্তর দিচ্ছেন, এবং সেই লোকেরা আপনার কোড পরামর্শের কারণগুলি জানেন না।
ফেরিবিগ

টিপ ফেরিবিগের জন্য ধন্যবাদ! কোডটিকে এটি সহজেই ছাড়িয়ে দেওয়া সহজ করার জন্য যতটা সম্ভব নথিভুক্ত করার চেষ্টা করেছি, আশা করি এটি সহায়তা করবে
নাহুয়েল রোল্ডান

0

এটি সুইফট 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
}

0

@ সামউইজ উত্তরটি উত্তরটিতে সুইফট 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
        })
    }

0

@ সামউইজের উত্তরটি সুইফট 5 এর জন্য আপডেট হয়েছে:

আপনি যদি সমস্ত ট্যাব পরিবর্তনগুলিতে অ্যানিমেশন রাখতে চান তবে একটি ইউআইটিববারকন্ট্রোলারডেলিগেট ব্যবহার করুন এবং এই পদ্ধতিটি প্রয়োগ করুন:

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
  })
}

-2

সুইফট 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
    });

}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.