iPhone: एक एनीमेशन के साथ टैब कैसे स्विच करें?


106

मैं टैब टैब प्रोग्राम का उपयोग करके टैब टैब को प्रोग्रामेटिक रूप से स्विच कर रहा हूं UITabBarController.selectedIndex। मैं जिस समस्या को हल करने की कोशिश कर रहा हूं वह यह है कि विचारों के बीच संक्रमण को कैसे चेतन किया जाए। अर्थात। वर्तमान टैब के दृश्य से चयनित टैब के दृश्य तक।

पहले सोचा था कि इसका उपयोग करना है UITabBarControllerDelegate, लेकिन ऐसा प्रतीत होता है कि जब प्रोग्राम स्विचिंग टैब्स होता है तो इसे नहीं कहा जाता है। अब मैं इस पर विचार कर रहा हूं UITabBarDelegate.didSelectItem: संक्रमण एनीमेशन को सेट करने के लिए एक संभावित हुक के रूप में।

किसी को भी संक्रमण चेतन करने में कामयाब रहा है? यदि हाँ, तो कैसे?


1
एफडब्ल्यूआईडब्ल्यू, इनमें से कई अत्यधिक जवाब दिए गए रनो के जवाब में उल्लिखित कस्टम बदलाव की भविष्यवाणी करते हैं और हेबर्टी भी । इन कस्टम एनिमेशन से निपटने का सही तरीका है। देखें नियंत्रकों का उपयोग करके WWDC 2013 के वीडियो कस्टम बदलाव देखें
रोब

जवाबों:


154

अपडेट 04/2016: जस्टेड सभी वोटों के लिए सभी को धन्यवाद कहने के लिए इसे अपडेट करना चाहता था। कृपया यह भी ध्यान दें कि यह मूल रूप से वापस लिखा गया था ... एआरसी से पहले, बाधाओं से पहले, ... बहुत सारा सामान! तो कृपया इन तकनीकों का उपयोग करने का निर्णय लेते समय इसे ध्यान में रखें। अधिक आधुनिक दृष्टिकोण हो सकते हैं। ओह, और यदि आप एक पाते हैं। कृपया प्रतिक्रिया जोड़ें ताकि सभी लोग देख सकें। धन्यवाद।

कुछ समय बाद ...

बहुत शोध के बाद मैं दो समाधान के साथ आया। इन दोनों ने टैब के बीच एनीमेशन पर काम किया और किया।

समाधान 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;                
                     }
                 }];

स्विफ्ट में यह समाधान:

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
उत्तर के लिए बहुत बहुत धन्यवाद, यह वास्तव में अच्छी तरह से काम करता है। हालाँकि, मुझे दोनों समाधानों में एक बग मिला, मुझे यकीन नहीं है कि यह हर किसी के साथ होता है, लेकिन ऐसा लगता है कि जब पृष्ठ को परिवर्तित किया जाता है, तो नेविगेशन बार और स्टेटस बार के बीच एक अंतर होता है, फिर एनीमेशन खत्म होने के बाद, अंतराल बंद हो जाता है। इससे एनीमेशन का अंत थोड़ा सा चिड़चिड़ा हो जाता है। क्या आप जानते हैं कि ऐसा क्यों हो रहा है?
एनरिको सुसात्यो

हम्म, मेरे कोड के साथ नहीं हो रहा था। यह एक मुद्दे की तरह लगता है जो मैंने पहले देखा है जहां खिड़की और स्थिति पट्टी के संबंध में नए विचारों के फ्रेम की स्थिति सही नहीं है। संक्रमण किए बिना विचारों को स्वैप करने के लिए पैर की अंगुली कोड चलाने की कोशिश करें और देखें कि क्या यह अभी भी होता है।
ट्रेक

हां, यह अभी भी एक संक्रमण करने के बिना होता है। मैंने पहला तरीका आजमाया। यह फ्रेम की स्थिति हो सकती है, मैं इसके साथ थोड़ा और अधिक खेलूंगा। मैंने फ्रेम को ऊपर स्थानांतरित करने की कोशिश की, और फ्रेम को
fromView से

2
@EmileCormier ने इसे TabBar डेलिगेट के shouldSelectViewControllerतरीके में डाल दिया और वहां कोई नहीं लौटा
cheesus

2
@drekka यह मेरे लिए काम नहीं कर रहा है। क्या आप समझा सकते हैं कि नियंत्रकइंडेक्स से आता है? और आप 'व्यू' के लिए tabBarControllerDelegate पद्धति से सिर्फ [viewController view] का उपयोग क्यों नहीं करते हैं? thnaks
shannoga

25

निम्नलिखित मेरे प्रतिनिधि में कोड फॉर्म ट्रेकका उपयोग करने की कोशिश है (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;
}

2
आपको विधि घोषणा के अनुसार कुछ मान वापस करना चाहिए, लेकिन यह तरीका अच्छा +1 काम करता है
voromax

2
आप प्रतिनिधि को अपनी UITabController कार्यान्वयन फ़ाइल में self.delegate = self जोड़कर सेट कर सकते हैं; अपने viewDidLoad () फ़ंक्शन में। यह उपरोक्त फ़ंक्शन को कॉल करने की अनुमति देगा।
क्रिस Fremgen

21

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

2
और TabViewController के प्रतिनिधि आउटलेट के लिए अपने प्रतिनिधि को हुक करने के लिए याद रखें। खूबसूरती से काम किया। सबसे साफ समाधान यहाँ।
एंड्रयू डंकन

क्या यह स्टोरीबोर्ड और स्विफ्ट के माध्यम से किया जा सकता है जो अब IOS 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

मुझे लगता है कि आप आसानी से CATransition का उपयोग करके UITabBarControlelr के लिए संक्रमण प्राप्त कर सकते हैं; यह ट्रांज़फ़ॉर्म व्यू का उपयोग करने के किसी भी दुष्प्रभाव को भी हल करेगा: 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"];
}

उम्मीद है की यह मदद करेगा :)


1
मुझे लगता है कि हम "doSelectViewController" के बजाय "didSelectViewController" का उपयोग कर सकते हैं
रयान वू

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

स्विफ्ट में मेरा समाधान:

कस्टम 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
 }

}

यह isos9 में काम नहीं कर रहा है - त्रुटि खोज विधि से लौटा है यानी '[UIViewController]?' '[UIViewController]' केवल अल्टरनेटिव ऑप्शंस; क्या आप '' का उपयोग करने का मतलब है?
lozflan

यह लगभग अच्छा था, सिवाय इसके कि मुझे एक बग का सामना करना पड़ा जो चेतन नहीं finishedहोगा ( झूठा होगा)। मुझे नहीं पता कि ऐसा क्यों होता है, लेकिन मुझे लगता है कि यह सीए परिवर्तन के साथ मिला जो सोचता है कि "एनिमेटेड कुछ भी नहीं" है। मैं फ्रेम के साथ animating के लिए बंद है, और वह काम किया।
samwize

3

मैंने @ मोफुमोफू के समाधान का उपयोग किया और इसे स्विफ्ट 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)
    }

}

3

यहाँ मेरा स्विफ्ट 3 समाधान है:

मैं इस तरह से अपने UITabBarViewController के चयनितइंडेक्स को ओवरराइड करता हूं:

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 को शामिल करना याद रखें (:) अपने AppDelegate.h में

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

उममीद है कि इससे मदद मिलेगी...!


1
मैं नेविगेशन नियंत्रकों के बीच परिवर्तन कैसे कर सकता / सकती हूं? TabBarControllerDelegate केवल व्यू कंट्रोलर्स के साथ काम करता है।
सईपी

मैंने दोनों की कोशिश की, पहले वाले ने नया दृश्य प्रदर्शित किया और एनिमेटेड की तुलना में यह अजीब लग रहा था। दूसरे को कोई असर नहीं हुआ। मैं टैब 2 से जुड़े दृश्य में गया और कोड को व्यूविलेयर में जोड़ा और इसका परीक्षण किया और टैब के साथ कोई विज़िबल एनीमेशन नहीं था।
शैनन कोल

डिफ़ॉल्ट Xcode TabBarController परियोजना के साथ इस एक की कोशिश की। 1 या 2 के साथ कोई भाग्य नहीं। मैं वास्तव में उन्हें काम करना चाहता था। :) क्या मुझे कुछ याद आ रहा है?
एंड्रयू डंकन

मुझे भी, कोई भाग्य नहीं .. कोई विचार?
जॉन

2

आप टेप किए गए आइटम के आधार पर चेतन कर सकते हैं - इस उदाहरण में हम फ्लिपफ्रेमलेफ्ट करते हैं यदि टैप किए गए इंडेक्स> पिछले चयनित इंडेक्स की तुलना में है और अगर टैप किए गए इंडेक्स पिछले चयनित इंडेक्स की तुलना में है तो हम फ्लिपफ्रॉमाइट को फ्लिप करते हैं। यह स्विफ्ट 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
}

ये काम नहीं कर रहा है। मैंने इसे व्यू कंट्रोलर में लागू किया है
devedv

@ देवेदव इस समाधान के साथ क्या काम नहीं कर रहा है? क्या आपने UITabBarControllerDelegate को अपने ViewController निर्धारित किया है?
तीतर

हाँ मैंने AppDelegate वर्ग में निम्नलिखित किया AppDelegate: UIResponder, UIApplicationDelegate, UITabBarControllerDelegate {}। मैं तेजी से नया हूँ क्या आप अपने उत्तर में चरणों को विस्तृत कर सकते हैं pls?
देवदेव

@ महादेव यदि यह आपका AppDelegate वर्ग है, तो अपने AppDelegate में फ़ंक्शन को ऊपर रखें और काम करना चाहिए
Tezz


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;

}


हालांकि यह कोड स्निपेट प्रश्न को हल कर सकता है, जिसमें स्पष्टीकरण सहित वास्तव में आपकी पोस्ट की गुणवत्ता में सुधार करने में मदद करता है। याद रखें कि आप भविष्य में पाठकों के लिए प्रश्न का उत्तर दे रहे हैं, और उन लोगों को आपके कोड सुझाव के कारणों का पता नहीं चल सकता है।
फेरीबिग

टिप Ferrybig के लिए धन्यवाद! मैंने इस कोड को दस्तावेज़ित करने की कोशिश की, जितना कि इसे कम करने के लिए आसान बनाना संभव है, आशा है कि यह मदद करता है
नाहुएल रोल्डन

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

@samwize उत्तर का स्विफ्ट 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 के लिए अपडेट किया गया जवाब :

यदि आप चाहते हैं कि सभी टैब परिवर्तनों में एनीमेशन हो, तो 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
  })
}

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

}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.