2013-08-20 14 views
23

Niedawno próbowałem pracować z MainStoryboard.storyboard w Xcode i do tej pory To idzie całkiem nieźle i zastanawiam się, dlaczego nigdy wcześniej go nie użyłem. Podczas gry z jakimś kodem wpadłem na przeszkodę i nie wiem, jak rozwiązać ten problem.Storyboard i niestandardowe init

Kiedy Alloc i init, nowy ViewController (z niestandardowego init, że zadeklarowane w klasie ViewControllers) Chciałbym zrobić coś takiego:

ViewController *myViewController = [[ViewController alloc] initWithMyCustomData:myCustomData]; 

Następnie po, że mogę zrobić coś takiego:

[self presentViewController:myViewController animated:YES completion:nil]; 

Kiedy pracuję z scenorysami, dowiedziałem się, że przejście na samodzielny ViewController wymaga identyfikatora.

UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil]; 
ViewController *myViewController = [storyboard instantiateViewControllerWithIdentifier:@"MyViewControllerIdentifier"]; 
[self presentViewController:myViewController animated:YES completion:nil]; 

Jak mogę nadal używać mojej własnej inicjalizacji dla myViewController podczas korzystania z storyboardu?

Czy można po prostu zrobić coś takiego:

UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil]; 
ViewController *myViewController = [storyboard instantiateViewControllerWithIdentifier:@"MyViewControllerIdentifier"]; 
myViewController.customData = myCustomData; 
[self presentViewController:myViewController animated:YES completion:nil]; 




//MyViewController.m 
- (id) initWithMyCustomData:(NSString *) data { 
if (self = [super init]) { 
    iVarData = data; 
} 
return self; 
} 

Odpowiedz

17

Chciałbym po prostu utworzyć metodę, która nie ładowanie niestandardowych danych.

UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil]; 
MyViewController *myViewController = [storyboard instantiateViewControllerWithIdentifier:@"MyViewControllerIdentifier"]; 
[myViewController loadCustomData:myCustomData]; 
[self presentViewController:myViewController animated:YES completion:nil]; 

Jeśli wszystko metoda initWithCustomData nie jest ustawiony jedną zmienną instancji, należy po prostu ustawić go ręcznie (nie ma zwyczaj inits lub dodatkowe metody wymagane):

UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil]; 
MyViewController *myViewController = [storyboard instantiateViewControllerWithIdentifier:@"MyViewControllerIdentifier"]; 
myViewController.iVarData = myCustomData; 
[self presentViewController:myViewController animated:YES completion:nil]; 
+14

Dzięki. Wygląda na to, że Apple nie zapewnia sposobu na stworzenie odpowiedniej niestandardowej metody "init" z Storyboard. – jowie

+2

Nie jestem pewien, dlaczego można by powiedzieć: "Jeśli cała twoja metoda initWithCustomData ma ustawioną jedną zmienną instancji, powinieneś ustawić ją ręcznie (nie są wymagane niestandardowe inicjały ani dodatkowe metody)". Nie ma żadnych dokumentów od Apple, które stwierdzają, że chciałbym, aby każdy czytelnik uznał to stwierdzenie za zwykłą opinię, a nie za regułę do naśladowania. Wiele inicjalizatorów w iOS przyjmuje nawet jeden argument. – zumzum

+0

@zumzum Apple stosuje praktykę ustawiania zmiennych w metodzie "prepareForSegue: sender:" w ich przykładowym kodzie. Zobacz plik "AddTimedReminder.m" w [EKReminderSuite] (https://developer.apple.com/library/prerelease/ios/samplecode/EKReminderSuite/Introduction/Intro.html#//apple_ref/doc/uid/TP40015203- Intro-DontLinkElementID_2) przykładowy projekt dla przykładu. –

16

Można instancję viewcontroller w metodzie -init .

- (instancetype)init 
{ 
    UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:[NSBundle mainBundle]]; 

    self = [storyboard instantiateViewControllerWithIdentifier:@"MyViewController"]; 

    if(self) 
    { 
    //default initialization 

    } 
    return self; 
} 

oraz w niestandardowej metody init,

- (instancetype)initWithImages:(NSArray *)images 
{ 
    self = [self init]; 

    if(self) 
    { 
    self.images = images; 
    } 

    return self; 
} 
+1

Nie sądzę, że możesz to zrobić w Swift ... –

+0

Tak, to może działać dla ObjC, ale nie w Swift. – Pranshu

2

Moja wersja:

- (instancetype)initWithData (NSArray *)someData 
{ 
    UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:[NSBundle mainBundle]]; 

    self = [storyboard instantiateViewControllerWithIdentifier:@"MyViewController"]; 

    if(self) 
    { 
    //default initialization 

    } 
    return self; 
} 

... jeden inicjator;)