8

sagen, dass ich eine benutzerdefinierte Container-View-Controller haben (Mainviewcontroller), wo ich so etwas tun:Container Ansicht Controller - benachrichtigen Eltern Handlungs

- (void)viewDidLoad 
{ 
    [super viewDidLoad];   

    HomeViewController *homeVC = [[HomeViewController alloc] initWithNibName:@"HomeViewController" bundle:nil]; 
    [self addChildViewController:homeVC]; 
    [self.view addSubview:homeVC.view]; 

} 

Die HomeViewController wird über eine Taste, wie „go“, dass Wenn Sie gedrückt werden, müssen Sie zum nächsten View-Controller wechseln. Also muss ich den MainViewController von dieser Aktion benachrichtigen. Was ist der beste Weg, dies zu tun?

Ich verwende einen benutzerdefinierten Container, weil ich benutzerdefinierte Übergänge zwischen den View-Controllern vornehmen muss. Wenn "go" gedrückt wird, werden einige Ansichten des HomeViewControllers animiert, während die Ansichten des neuen View-Controllers animiert werden.

Offensichtlich könnte ich dem HomeViewController eine Eigenschaft vom Typ MainViewController geben und Anrufe auf diese Weise machen, aber ich hoffe, dass es einen saubereren Weg mit der Container-View-Controller-API gibt.

Antwort

15

Sie können entweder delegieren oder blockieren;

Delegierter Mit

ein Protokoll erstellen:

@protocol SomeProtocol <NSObject> 
- (void)someAction; 
@end 

nur einen Delegierten in HomeViewController.h wie folgt erklären:

id<SomeProtocol> delegate; 

und dann in Mainviewcontroller des viewDidLoad gesetzt es so :

homeVC.delegate = self; 
//some where in MainViewController implement the protocol method 
-(void)someAction 
{ 
    //do something 
} 

dann, wenn Sie die Taste in homeVC drücken, rufen Sie einfach einfach:

if ([self.delegate respondsToSelector:@selector(someAction)]) { 
    [self.delegate someAction]; 
} 

Mit Block-:

In HomeViewController.h eine Blockeigenschaft deklarieren:

typedef void (^ActionBlock)(); 

@property (nonatomic, copy) ActionBlock block; 

dann in MainViewController ViewDidLoad:

homeVC.block = ^(){ 
    //do something 
}; 

dann, wenn Sie die Taste in homeVC drücken, rufen Sie einfach einfach:

self.block(); 
+0

ok, also gibt es nichts, was ich von der UIViewController Contain API nutzen kann? – soleil

+0

Nicht ganz sicher, dass dieser Beitrag helfen könnte [dies überprüfen] (http://stackoverflow.com/questions/8379759/how-does-view-controller-containment-work-in-ios-5-5) –

+1

Ich würde +1 das 3 mal, wenn ich könnte. Es beantwortete nicht nur die gleiche Frage für mich, aber es erweiterte mein Verständnis der Blöcke zehnfach :) – Pedro

10

gibt es eine andere Art und Weise zu ... Jeder View-Controller verfügt über eine parentViewController Eigenschaft so verwenden, dass Sie dies tun können ...

in MainViewController ein Verfahren für die Aktion, die Sie durchführen ...

- (void)someMethod:(BOOL)someParam; 

Dann sind Sie in HomeViewController wollen definieren tun können ...

MainViewController* parent = (MainViewController*)[self parentViewController]; 
[parent someMethod:paramValue]; 

HTH :)

+2

Gut schnell und schmutzig hier. Verwenden Sie die ausgewählte Antwort, wenn Sie etwas mehr Zeit haben, um das Protokoll zu erstellen. Danke Pedro! –

3

Dies ist ein sehr häufiges Muster.Die übergeordnete Instanz wird die tatsächliche Instanz sein, die die Aktion behandelt, indem sie eine und eine default extension bereitstellt.

In Swift 3:

Eltern-View-Controller:

protocol SomeProtocol { 
    func foo() 
} 

extension ParentViewController: SomeProtocol { 
    func foo() { 
     // Parent handles it 
    } 
} 

Child-View-Controller:

@IBAction func tapGo(_ sender: Any) { 
    (parent as? SomeProtocol)?.foo() 
} 
+0

Vielen Dank das war genau das, was ich gesucht habe :) – mic