iphone - नेविगेशन नियंत्रक ढेर, सबव्यू या मोडल नियंत्रकों का उपयोग किये बिना दृश्य नियंत्रकों में परिवर्तन को एनिमेट करें?




ios ipad (4)

आप ऐप्पल के नए दृश्य नियंत्रक नियंत्रण प्रणाली का उपयोग कर सकते हैं। अधिक गहन जानकारी के लिए डब्ल्यूडब्ल्यूडीसी 2011 सत्र वीडियो " UIViewController कंटेनमेंट कार्यान्वित करना" देखें।

आईओएस 5 के लिए नया, UIViewController कंटेंटेशन आपको अभिभावक दृश्य नियंत्रक और कई बच्चे दृश्य नियंत्रकों को इसके भीतर निहित करने की अनुमति देता है। इस प्रकार UISplitViewController काम करता है। ऐसा करने से आप अपने विशेष एप्लिकेशन के लिए अभिभावक में दृश्य नियंत्रकों को ढेर कर सकते हैं, लेकिन आप केवल एक दृश्य दृश्य नियंत्रक से संक्रमण को प्रबंधित करने के लिए अभिभावक का उपयोग कर रहे हैं। यह चीजों को करने और एक बच्चे के दृश्य से एनिमेट करने का ऐप्पल अनुमोदित तरीका है नियंत्रक दर्द रहित है। इसके अलावा आप सभी विभिन्न विभिन्न UIViewAnimationOption संक्रमणों का उपयोग करने के लिए मिलता है!

इसके अलावा, UIViewContainment के साथ, आपको चिंता करने की ज़रूरत नहीं है, जब तक आप बच्चे के दृश्य को प्रबंधित करने की गड़बड़ी के बारे में नहीं चाहते हैं, अभिविन्यास घटनाओं के दौरान नियंत्रक। आप बच्चे के दृश्य नियंत्रकों को अपने माता-पिता दृश्य नियंत्रक आगे रोटेशन ईवेंट सुनिश्चित करने के लिए निम्न का उपयोग कर सकते हैं।

- (BOOL)automaticallyForwardAppearanceAndRotationMethodsToChildViewControllers{
    return YES;
}

आप पहले बच्चे को देखने के लिए अपने माता-पिता के दृश्य में निम्न या समान कर सकते हैंडिल्ड लोडर विधि:

[self addChildViewController:self.currentViewController];
[self.view addSubview:self.currentViewController.view];
[self.currentViewController didMoveToParentViewController:self];
[self.currentViewController.swapViewControllerButton setTitle:@"Swap" forState:UIControlStateNormal];

तब जब आपको बच्चे के दृश्य नियंत्रक को बदलने की आवश्यकता होती है, तो आप पैरेंट व्यू कंट्रोलर के भीतर निम्न की पंक्तियों के साथ कुछ कहते हैं:

-(void)swapViewControllers:(childViewController *)addChildViewController:aNewViewController{
     [self addChildViewController:aNewViewController];
     __weak __block ViewController *weakSelf=self;
     [self transitionFromViewController:self.currentViewController
                       toViewController:aNewViewController
                               duration:1.0
                                options:UIViewAnimationOptionTransitionCurlUp
                             animations:nil
                             completion:^(BOOL finished) {
                                   [aNewViewController didMoveToParentViewController:weakSelf];

                                   [weakSelf.currentViewController willMoveToParentViewController:nil];
                                   [weakSelf.currentViewController removeFromParentViewController];

                                   weakSelf.currentViewController=[aNewViewController autorelease];
                             }];
 }

मैंने यहां एक पूर्ण उदाहरण परियोजना पोस्ट की है: https://github.com/toolmanGitHub/stackedViewControllers । यह अन्य प्रोजेक्ट दिखाता है कि कुछ विभिन्न इनपुट व्यू पर UIViewController Containment का उपयोग कैसे करें नियंत्रक प्रकार जो पूरी स्क्रीन नहीं लेते हैं। सौभाग्य

NavigationControllers के पास देखने के लिए ViewController ढेर हैं, और सीमित एनीमेशन संक्रमण।

मौजूदा व्यू कंट्रोलर को उप-दृश्य के रूप में व्यू कंट्रोलर जोड़ने के लिए सब-व्यू कंट्रोलर को ईवेंट पास करने की आवश्यकता होती है, जो प्रबंधन के लिए दर्द होता है, थोड़ा परेशानियों से भरा होता है और आम तौर पर लागू होने पर खराब हैक की तरह लगता है (ऐप्पल भी इसके खिलाफ सिफारिश करता है यह कर रहा हूं)।

एक मोडल व्यू कंट्रोलर प्रस्तुत करना फिर से दूसरे के शीर्ष पर एक व्यू कंट्रोलर रखता है, और जब ऊपर वर्णित घटनाओं को पार करने की घटना नहीं होती है, तो यह वास्तव में दृश्य नियंत्रक को 'स्वैप' नहीं करता है, यह इसे ढेर करता है।

स्टोरीबोर्ड आईओएस 5 तक सीमित हैं, और लगभग आदर्श हैं, लेकिन सभी परियोजनाओं में इसका उपयोग नहीं किया जा सकता है।

क्या कोई उपरोक्त सीमाओं के बिना दृश्य नियंत्रकों को बदलने के लिए एक ठोस कोड उदाहरण प्रस्तुत कर सकता है और उनके बीच एनिमेटेड संक्रमण की अनुमति देता है?

एक करीबी उदाहरण, लेकिन कोई एनीमेशन नहीं: नेविगेशन नियंत्रक के बिना एकाधिक आईओएस कस्टम व्यू कंट्रोलर का उपयोग कैसे करें

संपादित करें: एनवी कंट्रोलर का उपयोग ठीक है, लेकिन एनिमेटेड संक्रमण शैलियों (केवल स्लाइड प्रभाव नहीं) होने की आवश्यकता है, जिसे देखने वाले दृश्य नियंत्रक को पूरी तरह से स्वैप करने की आवश्यकता है (ढेर नहीं)। यदि दूसरे दृश्य नियंत्रक को स्टैक से एक और दृश्य नियंत्रक को हटाना होगा, तो यह पर्याप्त encapsulated नहीं है।

संपादित करें 2: आईओएस 4 इस प्रश्न के लिए आधार ओएस होना चाहिए, मुझे स्पष्ट करना चाहिए था कि स्टोरीबोर्ड (उपरोक्त) का उल्लेख करते समय।


चूंकि मैं अभी इस सटीक समस्या से हुआ हूं, और सीमित सफलता के सभी पूर्व-मौजूदा उत्तरों पर बदलावों की कोशिश की, मैं पोस्ट करूंगा कि मैंने अंततः इसे कैसे हल किया:

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

उपरोक्त लिंक ऊपर आईओएस 4 कोड प्रदान करता है ताकि वर्तमान शीर्ष दृश्य नियंत्रक को नेविगेशन कंट्रोलर स्टैक पर स्लाइड-इन-टू-टॉप एनीमेशन का उपयोग करके एक नए के साथ बदल दिया जा सके।

मेरे मामले में, मैं एक समान प्रतिस्थापन segue होने के लिए चाहता था, लेकिन एक FlipFromLeft संक्रमण के साथ। मुझे आईओएस 5+ के लिए केवल समर्थन की आवश्यकता है। कोड:

RAFlipReplaceSegue.h से:

#import <UIKit/UIKit.h>

@interface RAFlipReplaceSegue : UIStoryboardSegue
@end

RAFlipReplaceSegue.m से:

#import "RAFlipReplaceSegue.h"

@implementation RAFlipReplaceSegue

-(void) perform
{
    UIViewController *destVC = self.destinationViewController;
    UIViewController *sourceVC = self.sourceViewController;
    [destVC viewWillAppear:YES];

    destVC.view.frame = sourceVC.view.frame;

    [UIView transitionFromView:sourceVC.view
                        toView:destVC.view
                      duration:0.7
                       options:UIViewAnimationOptionTransitionFlipFromLeft
                    completion:^(BOOL finished)
                    {
                        [destVC viewDidAppear:YES];

                        UINavigationController *nav = sourceVC.navigationController;
                        [nav popViewControllerAnimated:NO];
                        [nav pushViewController:destVC animated:NO];
                    }
     ];
}

@end

अब, किसी अन्य प्रकार के सेग्यू को सेट करने के लिए कंट्रोल-ड्रैग करें, फिर इसे कस्टम सेग्यू बनाएं, और कस्टम सेग्यू क्लास के नाम पर टाइप करें, और voilà!


मैंने लंबे समय से इस के साथ संघर्ष किया, और मेरे मुद्दों में से एक here सूचीबद्ध here , मुझे यकीन नहीं है कि आपको वह समस्या है या नहीं। लेकिन अगर मैं आईओएस 4 के साथ काम करना चाहूंगा तो मैं यहां सलाह दूंगा।

सबसे पहले, एक नया NavigationController वर्ग बनाएँ। यह वह जगह है जहां हम सभी गंदे काम करेंगे - अन्य कक्षाएं pushViewController: जैसे कॉल इंस्टेंस विधियों को "साफ" करने में सक्षम होंगी pushViewController: और ऐसे। आपके .h :

@interface NavigationController : UIViewController {
    NSMutableArray *childViewControllers;
    UIViewController *currentViewController;
}

- (void)transitionFromViewController:(UIViewController *)fromViewController toViewController:(UIViewController *)toViewController duration:(NSTimeInterval)duration animations:(void (^)(void))animations completion:(void (^)(BOOL))completion;
- (void)addChildViewController:(UIViewController *)childController;
- (void)removeChildViewController:(UIViewController *)childController;

बाल दृश्य नियंत्रक सरणी हमारे ढेर में सभी दृश्य नियंत्रकों के लिए एक स्टोर के रूप में कार्य करेगा। हम स्वचालित currentController को NavigationController currentController दृश्य से कोड को सभी रोटेशन और आकार बदलने का स्वचालित रूप से अग्रेषित करेंगे।

अब, हमारे कार्यान्वयन में:

- (void)transitionFromViewController:(UIViewController *)fromViewController toViewController:(UIViewController *)toViewController duration:(NSTimeInterval)duration animations:(void (^)(void))animations completion:(void (^)(BOOL))completion
{
    currentViewController = [toViewController retain];
    // Put any auto- and manual-resizing handling code here

    [UIView animateWithDuration:duration animations:animations completion:completion];

    [fromViewController.view removeFromSuperview];
}

- (void)addChildViewController:(UIViewController *)childController {
    [childViewControllers addObject:childController];
}

- (void)removeChildViewController:(UIViewController *)childController {
    [childViewControllers removeObject:childController];
}

अब आप इन विधि कॉल का उपयोग करके अपने स्वयं के कस्टम pushViewController: popViewController और ऐसे कार्यान्वित कर सकते हैं।

गुड लक और मुझे उम्मीद है इससे मदद मिलेगी!


संपादित करें: नया उत्तर जो किसी भी अभिविन्यास में काम करता है। मूल उत्तर केवल तभी काम करता है जब इंटरफ़ेस पोर्ट्रेट अभिविन्यास में होता है। यह बी / सी व्यू संक्रमण एनीमेशन है जो दृश्य को प्रतिस्थापित करता है w / एक अलग दृश्य विंडो में जोड़े गए पहले दृश्य के नीचे कम से कम एक स्तर के दृश्यों के साथ होना चाहिए (जैसे window.rootViewController.view.anotherView )।

मैंने TransitionController नामक एक साधारण कंटेनर क्लास को कार्यान्वित किया है। आप इसे https://gist.github.com/1394947 पर पा सकते हैं।

एक तरफ के रूप में, मैं एक अलग वर्ग बी / सी में कार्यान्वयन को प्राथमिकता देना पसंद करता हूं। यदि आप यह नहीं चाहते हैं, तो आप TransitionController कक्षा की आवश्यकता को समाप्त करने के लिए सीधे अपने ऐप प्रतिनिधि में उसी तर्क को लागू कर सकते हैं। आपको जो तर्क चाहिए वह वही होगा।

इसे निम्नानुसार प्रयोग करें:

आपके ऐप प्रतिनिधि में

// add a property for the TransitionController

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    MyViewController *vc = [[MyViewContoller alloc] init...];
    self.transitionController = [[TransitionController alloc] initWithViewController:vc];
    self.window.rootViewController = self.transitionController;
    [self.window makeKeyAndVisible];
    return YES;
}

किसी भी व्यू कंट्रोलर से नए व्यू कंट्रोलर में संक्रमण करने के लिए

- (IBAction)flipToView
{
    anotherViewController *vc = [[AnotherViewController alloc] init...];
    MyAppDelegate *appDelegate = [UIApplication sharedApplication].delegate;
    [appDelegate.transitionController transitionToViewController:vc withOptions:UIViewAnimationOptionTransitionFlipFromRight];
}

संपादित करें: नीचे मूल उत्तर - केवल पोर्टेट अभिविन्यास के लिए काम करता है

मैंने इस उदाहरण के लिए निम्नलिखित धारणाएं की हैं:

  1. आपके पास एक विंडो नियंत्रक है जो आपकी विंडो के rootViewController व्यू कंट्रोलर के रूप में असाइन किया गया है

  2. जब आप किसी नए दृश्य पर स्विच करते हैं तो आप व्यू कंट्रोलर के साथ नए व्यू के मालिक के साथ वर्तमान व्यू कंट्रोलर को प्रतिस्थापित करना चाहते हैं। किसी भी समय, केवल वर्तमान दृश्य नियंत्रक जीवित है (उदाहरण के लिए आवंटित)।

कोड को आसानी से काम करने के लिए आसानी से संशोधित किया जा सकता है, मुख्य बिंदु एनिमेटेड संक्रमण और एकल दृश्य नियंत्रक है। सुनिश्चित करें कि आप window.rootViewController को असाइन करने के बाहर कहीं भी एक दृश्य नियंत्रक नहीं बनाए रखते हैं।

ऐप प्रतिनिधि में संक्रमण को एनिमेट करने के लिए कोड

- (void)transitionToViewController:(UIViewController *)viewController
                    withTransition:(UIViewAnimationOptions)transition
{
    [UIView transitionFromView:self.window.rootViewController.view
                        toView:viewController.view
                      duration:0.65f
                       options:transition
                    completion:^(BOOL finished){
                        self.window.rootViewController = viewController;
                    }];
}

उदाहरण दृश्य नियंत्रक में उपयोग करें

- (IBAction)flipToNextView
{
    AnotherViewController *anotherVC = [[AnotherVC alloc] init...];
    MyAppDelegate *appDelegate = (MyAppDelegate *)[UIApplication sharedApplication].delegate;
    [appDelegate transitionToViewController:anotherVC
                             withTransition:UIViewAnimationOptionTransitionFlipFromRight];
}




uianimation