2011-07-06 6 views
5

Projektuję bibliotekę statyczną iOS, która będzie używana przez innych programistów. Ta biblioteka musi dostarczyć własny modalny interfejs użytkownika. Poszukuję najprostszego sposobu zaprojektowania interfejsu między aplikacją a biblioteką, aby to osiągnąć. Potrzebuję tylko obsługi systemu iOS 4.0 i nowszych wersji.Jaki jest najprostszy sposób zaprojektowania biblioteki statycznej iOS, która zapewnia własny modalny interfejs użytkownika?

Szorstki architektura

Moja biblioteka statyczna ma bardzo prosty interfejs API z jednej klasy. Aplikacja AppDelegate tworzy instancję tej jednej klasy i ustawia się jako delegat, aby otrzymywać powiadomienia. Gdy aplikacja chce, aby biblioteka wyświetlała swój interfejs użytkownika, wywołuje pojedynczą metodę, a kiedy biblioteka zakończy pracę, wysyła powiadomienie za pomocą jednej z metod protokołu delegata.

Widzę dwa sposoby osiągnięcia tego.

Wariant 1

Gdy aplikacja chce pokazać swoją bibliotekę do UI The AppDelegate przechodzi w self.window, a biblioteka ustawia swój własny kontroler widoku głównego, skutecznie biorąc pełną odpowiedzialność za UI. Po zakończeniu interfejsu użytkownika powiadamia AppDelegate, który następnie ustawia swój własny kontroler widoku root w oknie, odbierając własność interfejsu użytkownika.

Wariant 2

Biblioteka naraża kontroler widoku, który aplikacja może naciskać na cokolwiek widok stosu to lubi. Aplikacja jest również odpowiedzialna za usunięcie kontrolera widoku, gdy biblioteka powiadomi go, że interfejs został zakończony.

Problemy

z opcją 1, mogą pojawić się problemy zmieniające zobacz korzeń kontrolerów podczas gdy w środku działa aplikacja. W przypadku opcji 2 mogą pojawić się problemy z udostępnieniem kontrolera widoku, który może działać w dowolnym kontekście (jako kontroler widoku pełnoekranowego, jako podmenu UINavigationController, itp.).

Kolejny problem z obiema opcjami to inne powiadomienia UIApplicationDelegate, które może odbierać AppDelegate, takie jak applicationWillResignActive: i applicationDidBecomeActive :. Biblioteka może potrzebować obsługi takich powiadomień, aby poprawnie zachować swój interfejs użytkownika. Czy AppDelegate musi przekazać każdą z nich do biblioteki, gdy jej interfejs jest aktywny?

Czy istnieje lepsza opcja 3, o której nie pomyślałem?

Odpowiedz

3

Oto jak to zrobić: W swojej statycznej biblioteki utworzyć UIViewController i wszystkie widoki treści, które trzeba programowo (ponieważ nie można łatwo Ramki na iOS zdołasz zasoby nie łatwo zapakować):

UIViewController *controller = [[[UIViewController alloc] initWithNibName: nil bundle: nil] autorelease]; 
UIView *containerView = [[[UIView alloc] initWithFrame: [UIScreen mainScreen].applicationFrame] autorelease]; 
containerView.backgroundColor = [UIColor darkGrayColor]; 

UIWebView *webView = [[[UIWebView alloc] initWithFrame: containerView.bounds] autorelease]; 
webView.delegate = self; 

// ... some other code to setup custom things 

[containerView addSubview: webView]; 

// ... some other code to setup custom things, spinner etc. 

następnie wyświetlać je

[[UIApplication sharedApplication].keyWindow.rootViewController presentModalViewController: myViewController animated: YES]; 

To jest wycinane i wklejane z pracy biblioteki statycznej, który został osadzony w dwóch różnych aplikacjach na iOS i wydaje się działać dobrze w obu. Mogą to być skrajne przypadki, które nie obejmują, ale jeszcze ich nie uderzyłem :)

+0

Czy musimy napisać ten kod w klasie NSObject –

+0

Prawie każda klasa, w której to umieściliśmy jest pochodną NSObject i musi to być kod ObjectiveC, więc nie jestem pewien, czy rozumiem twoje pytanie. Zwróć uwagę, że jest to> 2 lata, więc nie mamy pewności, czy jest ono aktualne. – Dad

+0

Tnx za odpowiedź Twój kod działa dobrze. To był błąd w moim kodzie. świetny kod to zaoszczędzić mój czas dużo .. –

1

Użyj bloków zamiast delegata. Twój widok powinien wywołać podaną wartość dismissBlock przechowywaną w obiekcie, a osoba dzwoniąca może zrobić to, co musi zrobić z tego bloku. Masz dane, które musisz przekazać? Ustaw jako argument bloku lub umieść go we właściwości obiektu dostępnego z kontrolera widoku, stosownie do potrzeb.

Jeśli masz stan, który wymaga zapisania w odpowiedzi na zdarzenie, udokumentuj i podaj sposób zapisania tych informacji w niektórych danych i przywróć interfejs z bloku danych. Dzwoniący może obsłużyć to, co chce.

To, jak interfejs będzie wyświetlany w sposób modalny, powinno należeć do aplikacji klienckiej, ale pod warunkiem, że interfejs musi rzeczywiście być wyświetlany modalnie, ogranicza się dostatecznie środowisko, aby nie martwić się zbytnio środowiskiem hosta. .

5

Czy bierzesz pod uwagę projektując API zaakceptować UIViewController:

- (void)presentFromViewController:(UIViewController *)presentingViewController 
         animated:(BOOL)animated 
{ 
    [presentingViewController presentModalViewController:myViewController 
               animated:animated]; 
} 

ten sposób, biblioteka posiada pełną kontrolę nad tym, w jaki sposób UI modalne przedstawiono, i może też nazywać się -dismissViewControllerAnimated: zamiast polegać na delegata aby to zrobić.

Nie przejmuj się omijać -applicationWillResignActive: itp. Wystarczy zarejestrować się w celu uzyskania podstawowych powiadomień UIApplicationWillResignActiveNotification itp. W swojej klasie biblioteki.