Frage

Ich habe zwei Ansichten, die Notwendigkeit modal angezeigt werden, eine nach der anderen. Das funktioniert nicht, wenn wir nacheinander entlassen und zeigen, wie folgt aus:

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

Die zweite modale Ansicht einfach nicht angezeigt.

Ich habe ein Update gesehen, dass so etwas wie dies:

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

Das Problem ist, dass dies nicht die ganze Zeit arbeiten (die Verzögerung erforderlich ist überlegen, manchmal).

Eine andere mögliche Lösung wäre die Animation zu beseitigen:

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

Aber ich würde wirklich gern die Animation halten, um das Gefühl zu halten, dass die erste modal ist der Ausweg. Irgendwelche Vorschläge?

War es hilfreich?

Lösung

EDIT:. der "richtige" -Mechanismus dies in iOS5 + zu tun, wäre es, die – dismissViewControllerAnimated:completion: Methode zu verwenden, und legt die sequenziellen View-Controller aus der Fertigstellung Block


Der Viewcontroller, die modal angezeigt wird, wird seine viewDidDisappear haben: animierte: Methode aufgerufen, sobald die modal-Entlassung-Animation abgeschlossen ist. Afik dies ist der Ort, nur können Sie einen nachfolgenden PresentModalViewController zu initiieren Haken: animated: Tel.

Ich habe eine Klasse, dass ich für die Darstellung modal View-Controller verwenden, und es implementiert die Logik, die Sie gesucht haben, um auf die Präsentation View-Controller über einen Rückruf suchen, sobald die Kündigung abgeschlossen ist. Um diese Klasse zu verwenden, einfach alloc / init eine Instanz und Gegenwart des normalen presentViewController mit: animated: Anruf. Implementieren Sie die folgende Methode auf den präsentierenden View-Controller:

- (void) modalViewControllerDidDismiss:(UIViewController *)modalViewController

Das bei aufgerufen wird, sobald der modal-View-Controller ist weg, und Sie können zu diesem Zeitpunkt einen neuen modalen View-Controller präsentiert.

Auch Eine nette Sache - da diese Klasse eine Spezialisierung von UINavigationController ist, können Sie die Navigationsleiste ein / aus konfigurieren, wie Sie möchten. Die Klasse hat auch eingebaute Logik eine Taste abweisen zeigen, wie Sie möchten.

Hier ist die Klassendefinition:

@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

Und die Klassenimplementierung:

@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

und hier ist, wie Sie es (im Rahmen von einigen normalen View-Controller) verwenden können:

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

und hier ist die Entlassung Callback-Methode, die präsentiert ein neuer Modal-View-Controller:

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

Andere Tipps

rootController kann sagen, wann der letzte der modal View-Controller auf es verschwunden ist, weil es eine viewDidAppear erhalten :. Haben Sie versucht, die Verknüpfung der PresentModalViewController: der nachfolgenden View-Controller, dass

Wenn Sie wirklich an der Kette mehr Ansicht Animationen wollen zusammen, würde ich vorschlagen, tatsächlich Handhabung nur die Animation Logik selbst. Es ist nicht zu schwierig, und dann kann man feinkörnige Kontrolle darüber, wie die Ansichten dargestellt. Ich schrieb hier etwas ähnliches für eine weitere Frage auf:

iOS - wie steuern Sie die Größe eines modal view-Controller

Sie können nur die Aussicht auf animieren, animieren die Ansicht aus, und wenn Ihr animationDidStop Selektor genannt wird, animieren Ihren zweiten Blick auf. Das schöne daran ist, Sie auch mit Blick Opazität und Animationsrichtung spielen können, sowie genau entscheiden, wann die Ansichten angezeigt werden sollen. Zum Beispiel könnten Sie die zweite Ansicht gekommen sind Schiebe als erste Blick auf den ersten Blick nach oben gleitet weg; keine Notwendigkeit für die ersten zu warten, seine Animation zu beenden.

Ist Ihr Problem im Zusammenhang mit „innerhalb einer modalen Ansicht eine modale Ansicht zeigen“? Ich habe eine Antwort über diese Nachricht hier: iPhone modale Ansicht in einer anderen modalen Ansicht?

Die beste Lösung, die ich für so etwas gefunden (wenn sie alle gleich Kinder von der übergeordneten Ansicht ist) ist, ihre Ansichten auf einem UIScrollView Patch mit Paging aktiviert ist, (können Sie eine Seite Kontrolle am Boden hinzufügen, um es zu löschen und für die Navigation), dann die Ansichten des Controller auf die Seite Ansicht hinzufügen, wie sie auf dem Bildschirm kommen, entfernen, wie sie gehen außerhalb des Bildschirms.

Sie können auch Dummy-Anruf -viewWillAppear und -viewWillDisappear haben, wenn die Controller verlassen diese aufgerufen wird. Es fühlt sich ein bisschen hack-ish, wenn Sie es sind Codierung alle, aber wenn Sie es haben funktioniert es aussieht und natürlich glatt, und es ist nicht von der mit Animieren einer Ansicht aus assoziierten warten, dann in, wenn es das nächste Animieren weg ist.

ich mit der modalen Ansicht des -viewDidDissapear finde Methoden aufzurufen auf der Präsentation View-Controller-Arbeit sehr gut ist. Ein Vorteil ist die Fähigkeit, Deallokation auf den Modal-View-Controller zu verzögern. Bitte senden Sie alle Verbesserungen, die ich machen kann. Meine Inspiration für dieses Protokoll zu schaffen kam von iOS 5 ist „dismissViewControllerAnimated: Abschluss:“ Neben UIViewController. Ich wollte diese Funktionalität in iOS 4.3.


PresentorDelegateProtocol.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];

                }
            }];
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top