سؤال

لديّ عرضان يحتاجان إلى عرضه بشكل معدني ، واحدة تلو الأخرى. هذا لا يعمل إذا رفضنا ونظهر على التوالي ، مثل هذا:

[rootController dismissModalViewControllerAnimated: YES];
[rootController presentModalViewController: psvc animated: YES];

العرض الوسيط الثاني ببساطة لا يظهر.

لقد رأيت إصلاحًا كان شيئًا من هذا القبيل:

[rootController dismissModalViewControllerAnimated: YES];
[[UIApplication sharedApplication] beginIgnoringInteractionEvents];
[self performSelector: @selector(seekModal) withObject: nil afterDelay: 0.5];
[[UIApplication sharedApplication] endIgnoringInteractionEvents];

المشكلة هي أن هذا لن يعمل طوال الوقت (التأخير المطلوب هو متفوق ، في بعض الأحيان).

هناك حل آخر ممكن هو القضاء على الرسوم المتحركة:

[rootController dismissModalViewControllerAnimated: NO];
[rootController presentModalViewController: psvc animated: YES];

لكنني أود حقًا الحفاظ على الرسوم المتحركة ، للحفاظ على الشعور بأن الوسيط الأول بعيدًا عن الطريق. أي اقتراحات؟

هل كانت مفيدة؟

المحلول

تعديل: الآلية "الصحيحة" للقيام بذلك في iOS5+ هي استخدام – dismissViewControllerAnimated:completion: الطريقة ، وقدم وحدة تحكم العرض المتسلسلة من كتلة الانتهاء.


سيكون ViewController الذي يتم عرضه بشكل أساسي سيكون له ViewDidDisAppear: الرسوم المتحركة: الطريقة التي تسمى بمجرد اكتمال التكوين الوسيط. AFIK هذا هو المكان الوحيد الذي يمكنك ربطه لبدء برنامج PresentModalViewController اللاحق: الرسوم المتحركة: اتصل.

لدي فئة أستخدمها لتقديم وحدات التحكم في العرض المشروط وهي تنفذ المنطق الذي تبحث عنه عبر رد اتصال إلى وحدة التحكم في العرض بمجرد اكتمال الفصل. لاستخدام هذه الفئة ، ما عليك سوى تخصيص/init مثيلًا والحصول على استخدام PresentViewController العادي: الرسوم المتحركة: اتصل. قم بتنفيذ الطريقة التالية على وحدة تحكم عرض العرض:

- (void) modalViewControllerDidDismiss:(UIViewController *)modalViewController

سيتم استدعاء ذلك مرة واحدة على وحدة التحكم في العرض الوسيط ، ويمكنك تقديم وحدة تحكم عرض مشروط جديدة في هذا الوقت.

شيء واحد لطيف أيضًا - نظرًا لأن هذه الفئة هي تخصص في UinavigationController ، يمكنك تكوين on/Off on/OFF كما تريد. يحتوي الفصل أيضًا على منطق مدمج لإظهار زر الفصل ، كما تريد.

هذا هو تعريف الفصل:

@protocol TSModalViewControllerDelegate

- (void) modalViewControllerDidDismiss: (UIViewController*) modalViewController;

@end

@interface TSModalViewController : UINavigationController 
{
    UIViewController*   _originalParentViewController;
}
@property BOOL dismissButtonHidden;

- (id) initWithViewController: (UIViewController*) vc;
- (id) initWithClass: (Class) c;
- (id) initWithClass: (Class) c nibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil;

@end

وتنفيذ الفصل:

@implementation TSModalViewController
@synthesize dismissButtonHidden;

- (id) initWithViewController: (UIViewController *)vc
{
    return [super initWithRootViewController: vc];
}

- (id) initWithClass:(Class)c
{
    UIViewController* vc = [[[c alloc] init] autorelease];
    return [self initWithViewController: vc];
}

- (id) initWithClass: (Class) c nibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    UIViewController* vc = [[[c alloc] initWithNibName:nibNameOrNil bundle:nibBundleOrNil] autorelease];
    return [self initWithViewController: vc];
}

- (void) viewDidAppear: (BOOL) animated
{
    [super viewDidAppear: animated];

    [_originalParentViewController release];
    _originalParentViewController = [self.parentViewController retain];

    if (!self.dismissButtonHidden)
    {
        UIBarButtonItem* dismissButton = [[[UIBarButtonItem alloc] initWithBarButtonSystemItem: UIBarButtonSystemItemStop
                                                                                        target: self 
                                                                                        action: @selector(onDismiss:)] autorelease];

        UIViewController* rootViewController = [self.viewControllers objectAtIndex:0];

        rootViewController.navigationItem.leftBarButtonItem = dismissButton;
        self.navigationBarHidden = NO;
    }   
}

- (void) viewDidDisappear:(BOOL)animated
{
    [super viewDidDisappear: animated];
    if ( [_originalParentViewController respondsToSelector: @selector(modalViewControllerDidDismiss:)] )
    {
        [_originalParentViewController performSelector: @selector(modalViewControllerDidDismiss:) withObject: self];
    }
}

- (void) dismissModalViewControllerAnimated:(BOOL)animated
{
    return [self.parentViewController dismissModalViewControllerAnimated: animated];
}

- (void) onDismiss: (id) sender
{
    [self.parentViewController dismissModalViewControllerAnimated: YES];
}

- (void) didReceiveMemoryWarning 
{
    [super didReceiveMemoryWarning];
}

- (void) viewDidUnload 
{
    [super viewDidUnload];
}

- (void)dealloc 
{
    [_originalParentViewController release];
    [super dealloc];
}

@end

وإليك كيف يمكنك استخدامه (في سياق بعض وحدة تحكم العرض العادية):

- (void) onShowIt:(id)sender
{
    TSModalViewController* mvc = [[[TSModalViewController alloc] initWithClass: [MyModalViewController class] nibName: @"MyModalViewController" bundle:nil] autorelease];
    mvc.dismissButtonHidden = YES;  // set to no if you don't want an "automatic" close button

    [self presentModalViewController: mvc animated: YES];
}

وهنا طريقة رد الاتصال ، والتي تقدم وحدة تحكم عرض مشروط جديدة:

- (void) modalViewControllerDidDismiss:(UIViewController *)modalViewController
{
    MyModalViewController* vc = [[[MyModalViewController alloc] initWithNibName: @"MyModalViewController" bundle:nil] autorelease];
    vc.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;

    TSModalViewController* mvc = [[[TSModalViewController alloc] initWithViewController: vc] autorelease];

    [self presentModalViewController: mvc animated: YES];
}

نصائح أخرى

يمكن لـ RootController معرفة متى اختفى آخر وحدات التحكم في العرض المشروط فوقها لأنه سيتلقى ViewDidAppear :. هل حاولت ربط presentModalViewController: من وحدة تحكم العرض اللاحقة إلى ذلك؟

إذا كنت ترغب حقًا في ربط الرسوم المتحركة متعددة العرض معًا ، فأنا أقترح في الواقع مجرد التعامل مع منطق الرسوم المتحركة بنفسك. إنه ليس صعبًا للغاية ، وبعد ذلك يمكنك التحكم في الحبيبات الدقيقة حول كيفية تقديم المشاهدات. لقد كتبت للتو شيئًا مشابهًا لسؤال آخر هنا:

iOS - كيف يمكنك التحكم في حجم وحدة تحكم العرض الوسائط؟

يمكنك فقط تحريك العرض ، وتحريك العرض ، وعندما يتم استدعاء محدد الرسوم المتحركة الخاصة بك ، قامت بتحريك عرضك الثاني. الجزء الجميل من هذا هو أنه يمكنك أيضًا اللعب مع عرض العتامة واتجاه الرسوم المتحركة ، وكذلك تحديد متى يجب أن تظهر المشاهدات. على سبيل المثال ، يمكن أن يكون العرض الثاني ينزلق فوق العرض الأول حيث أن العرض الأول ينزلق بعيدًا ؛ لا حاجة لانتظار أول واحد لإكمال الرسوم المتحركة.

هل تتعلق مشكلتك بـ "إظهار عرض مشروط داخل عرض مشروط"؟ لقد قمت بنشر إجابة حول هذا هنا:طريقة العرض الوسيطة iPhone داخل عرض مشروط آخر؟

أفضل حل وجدته لشيء من هذا القبيل (إذا كانوا جميعهم أطفال متساوين في طريقة عرض الوالدين) هو تصحيح وجهات نظرهم على مقابلة مع تمكين الترحيل ، (يمكنك إضافة عنصر تحكم في الصفحة في الأسفل لتوضيحها وللحركية. ) ثم أضف طرق عرض وحدات التحكم إلى عرض الصفحة عند ظهورها على الشاشة ، قم بإزالةها أثناء خروجها من الشاشة.

قد تضطر أيضًا إلى المكالمات الوهمية -ViewWillAppear و -viewWillDisAppear إذا كانت وحدات التحكم تعتمد على ذلك. يبدو الأمر نوعًا ما عند الاختراق عندما تقوم بترميز كل شيء ، ولكن بمجرد أن تعمل ، يبدو ناعمًا وطبيعيًا ، وليس هناك أي من الانتظار المرتبط بعرض واحد ذهب.

أجد استخدام طريقة العرض الوسيطة -ViewDiddissapear لاستدعاء الأساليب في عمل وحدة التحكم في العرض بشكل جيد للغاية. إحدى الفوائد هي القدرة على تأخير تحديد التخصيص على وحدة تحكم العرض الوسيطة. يرجى نشر أي تحسينات يمكنني إجراؤها. جاء مصدر إلهامي لإنشاء هذا البروتوكول من "DisissViewControllerAnimated:" الإكمال: "بالإضافة إلى UiviewController. أردت هذه الوظيفة في iOS 4.3.


PresentOdleGateProtocol.H

@protocol PresentorDelegateProtocol <NSObject>
@optional

/* 

Extra protocol methods defined in protocol for flexibility.  
Main methods are:
- (void)dismissPresentingModalViewController:(id)modalView animated:(BOOL)animated; 
- (void)modalViewDissapeared:(id)modalView;  //used in modal view's -viewDidDissapear

*/

- (void)dismissPresentingModalViewController:(id)modalView animated:(BOOL)animated;
- (void)modalViewDissapeared:(id)modalView; 

// use the block in this method send messages to save state, etc.  This is the one I like to use.
- (void)dismissPresentingModalViewController:(id)modalView animated:(BOOL)animated withBlock:(void(^)())block;

// use in other classes that are not controlling dismissal of the modal view
- (void)executeBlockOnModalDissapearance: (void(^)())block;

@end

PresentingViewController.H

#import "PresentorDelegateProtocol.h"
@interface PresentingViewController : UIViewController <PresentorDelegateProtocol>
- (void)showModalVC;
@end

ModalViewController.H

#import "PresentorDelegateProtocol.h"
@interface ModalViewController : UIViewController
@property (nonatomic, assign) id <PresentorDelegateProtocol> presentorDelegate;
- (void)close;
@end

PresentingViewController.M

#import "PresentingViewController.h"
#import "ModalViewController.h"
@implementation PresentingModalViewController
- (void)showModalVC
{
    ModalViewController *modalVC = [[ModalViewController alloc] initWithNibName:@"ModalViewController" bundle:nil];
    modalVC.presentorDelegate = self;
    [self presentModalViewController:modalVC animated:YES];
}
- (void)dismissPresentingModalViewController:(id)modalView animated:(BOOL)animated
{
    if ([modalView isKindOfClass:[ModalViewController class]]) {
        NSLog(@"Can invoke based on class"); 
    }
    [self dismissModalViewControllerAnimated:animated];    
}
- (void)dismissPresentingModalViewController:(id)modalView animated:(BOOL)animated withBlock:(void(^)())block
{
    block();  
    /* execute block before or after calling to dismiss modal view */
    [self dismissPresentingModalViewController:modalView animated:animated];
    //block();
}
- (void)modalViewDissapeared:(id)modalView
{
    if ([modalView isKindOfClass:[ModalViewController class]]) {
        NSLog(@"Do stuff based on class.");
    }
}
- (void)executeBlockOnModalDissapearance: (void(^)())block
{
    block();
    NSLog(@"This delay's dealloc on modal view until block completes");
}
@end

ModalViewController.M

#import "ModalViewController.h"
@implementation ModalViewController
@synthesize presentorDelegate;

- (void)close
{
    if (1 == 0 /*need to do something before dealloc*/){
        [self.presentorDelegate dismissPresentingModalViewController:self animated:YES withBlock:^{
            NSLog(@"Do stuff with block.  Save, animate, etc");
        }];

    } else {
        [self.presentorDelegate dismissPresentingModalViewController:self animated:YES];
    }
}

- (void)viewDidDisappear:(BOOL)animated
{
    if (1 == 0 /*stuff to do*/){
        [self.presentorDelegate executeBlockOnModalDissapearance:^{
        // do stuff before modal view is deallocated
        }];
    }
    [self.presentorDelegate modalViewDissapeared:self];

    presentorDelegate = nil;
    [super viewDidDisappear:animated];
}
@end;
// present modal view inside another presented modal view

    FirstViewController *firstVC = [[FirstViewController alloc] initWithNibName:@"FirstViewController" bundle:nil];
    UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController: firstVC];

    // Note: you can use your viewcontroller instead self.window.rootViewController

    [self.window.rootViewController presentViewController:navController animated:YES completion:^{
                //code...
                    SecondViewController *secondVC = [[SecondViewController alloc] initWithNibName:@"SecondViewController" bundle:nil];

                    [navController presentViewController: secondVC animated:YES completion:nil];

                }
            }];
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top