6

Tło: Chciałbym odwołać modalView że mam podane wcześniej i od razu obecny samo viewController że po prostu oddalił się z nowymi informacjami.iOS: Lekceważenie i Przedstawiając ModalViewController bez dostępu do jego rodzica ViewController

Problem: I nie były bardzo udane w ten sposób bez wyraźnej wskazówki dla rodziców ViewController że przedstawiła pierwsze ViewController modally. Próbuję napisać tę klasę, która działa bez zakłócania z poprzedniego kodu viewController.

Możliwa ołowiu: Istnieje kilka rzeczy, które mi zostały eksperymentujących z:

1.) usiłuje uzyskać dostęp do rodzica ViewController, który w tej chwili nie wiem jak.

2.) Gdy dostęp do rodzica jest zdobyte, mogę po prostu zastosować następujący kod:

UIViewController* toPresentViewController = [[UIViewController alloc] init]; 
    [self dismissViewControllerAnimated:YES completion:^{ 
     [parentViewControllerAccessor presentModalViewController:toPresentViewController animated:YES]; 
}]; 

W teorii powinno to działać ze względu na dostęp do rodzica viewController. Jestem otwarty na inne sposoby robienia tego.

Założenie: Nie masz uprawnień do zmiany jakiegokolwiek kodu w rodzicu ViewController.

Odpowiedz

11

swój wygląd kod tak jak powinno działać. Jeśli korzystasz z systemu iOS 5, istnieje właściwość UIViewController o nazwie presentingViewController.

@property(nonatomic, readonly) UIViewController *presentingViewController; 

Dzięki tej właściwości można uzyskać kontroler widoku, który przedstawił kontroler modalny.

Uwaga: W iOS 4 parentViewController będzie ustawiona na regulatorze przedstawienia, więc jeśli wspierają zarówno iOS 4 i 5 będzie trzeba sprawdzić wersję OS najpierw zdecydować, która to właściwość, aby uzyskać dostęp. W systemie iOS 5 Apple naprawił to tak, że parentViewController jest obecnie używany wyłącznie dla nadrzędnych kontrolerów widoku zawartych (patrz: sekcja Implementacja kontrolera widoku kontenera w dokumentacji UIViewController).

Edit: Odnośnie dostępu self.presentingViewController od wewnątrz bloku: Kiedy blok jest nazywany (po modalne kontroler widoku zostaje odrzucona) nieruchomość presentingViewController może się ustawić na zero. Pamiętaj, że self.presentingViewController wewnątrz bloku podaje wartość właściwości, gdy blok jest wykonywany, a nie kiedy został utworzony.Aby zabezpieczyć się przed tym wykonać następujące czynności:

UIViewController* toPresentViewController = [[UIViewController alloc] init]; 
UIViewController* presentingViewController = self.presentingViewController; 
[self dismissViewControllerAnimated:YES completion:^ 
{ 
    [presentingViewController presentModalViewController:toPresentViewController animated:YES]; 
}]; 

Jest to konieczne nie dlatego self zniknął/odwołany (jest bezpiecznie zatrzymywane przez blok), ale dlatego, że nie jest już przedstawiony, dlatego jego presentingViewController jest zerowe. Nie jest konieczne przechowywanie w innym miejscu zmiennej lokalnej, ponieważ będzie ona zachowywana przez blok.

+0

Jeśli rozumiem to poprawnie, powinienem zmienić ten kod: '[parentViewControllerAccessor presentModalViewController: toPresentViewController animated: YES];' to '[self.presentingViewController presentModalViewController: croppedPhotoVC animated: YES];'. Niestety, wydaje się, że to nie działa. Czy rozumiem coś niepoprawnie? – Byte

+1

Dzieje się tak prawdopodobnie z powodu tego, jak bloki zachowują obiekty - zachowują siebie, ale nie przedstawiają kontrolera widoku, więc do czasu, gdy "ja" zostało odrzucone, ta właściwość może zostać ustawiona na zero. Ustaw self.presentingViewController na zmienną lokalną poza blokiem, a następnie użyj tej zmiennej z bloku. – jhabbott

+0

To ten sam wniosek, który wymyśliłem. Być może będę musiał stworzyć zmienną statyczną, aby utrzymać to tak, że gdy 'self' zostanie usunięty, metoda będzie nadal działać. Ale to wygląda bardziej jak włamanie. – Byte

1

Możesz to zrobić, korzystając z powiadomień.

Na przykład ogień to powiadomienie zza pola widzenia modalnej kiedy chcesz zostać odwołany:

[[NSNotificationCenter defaultCenter] postNotificationName:@"dismissModalView" 
                object:nil 
                userInfo:nil]; 

A potem obsłużyć to powiadomienie wewnątrz modalnej widzenia:

- (void)viewDidLoad { 
    [[NSNotificationCenter defaultCenter] addObserver:self 
              selector:@selector(dismissMe:) 
               name:@"dismissModalView" 
               object:nil]; 
} 

- (void)dismissMe:(NSNotification)notification { 
    // dismiss it here. 
} 
+0

„a następnie obsługiwać to powiadomienie wewnątrz modalnej widzenia:” Nie jestem pewien, co to niby ma znaczyć, ja jednoznacznie powiedział, nie mogę dotknąć kodu na poprzednim viewController, który prezentuje ten viewController. Chyba, że ​​coś tu nie rozumiem? – Byte

1

rozwiązanie dla iOS5:

-(void)didDismissModalView:(id)sender { 

    // Dismiss the modal view controller 
    int sold=0; 

    if(sold==0){ 

     //Cash_sold.delegate = self; 
     // Cash_sold.user_amount.text=[NSString stringWithFormat:@"%d",somme]; 

     Cash_sold = [[CashSoldview alloc] initWithNibName:@"CashSoldview" bundle:nil]; 
     CGRect fram1 = CGRectMake(200,20,400,400); 
     Cash_sold.view.superview.frame = fram1; 
     Cash_sold.view.frame=fram1; 
     Cash_sold.modalTransitionStyle= UIModalTransitionStyleCoverVertical; 
     Cash_sold.modalPresentationStyle=UIModalPresentationFormSheet; 

     UIViewController* presentingViewController = self.parentViewController; 

     [self dismissViewControllerAnimated:YES completion:^ 
     { 
     [presentingViewController presentModalViewController:Cash_sold animated:YES]; 
     }];  
    } 
} 
1

Wypróbuj poniższy kod:

[self dismissViewControllerAnimated:NO 
         completion:^{ 
    // instantiate and initialize the new controller 
    MyViewController *newViewController = [[MyViewController alloc] init]; 
    [[self presentingViewController] presentViewController:newViewController 
               animated:NO 
               completion:nil]; 
}]; 
+0

bardzo krótki kod, a także działa dobrze .. – svmrajesh