Niestandardowe widoki dzięki Storyboard

96

Na złożonych ekranach (kontrolery widoku) zwykłem rozdzielać całość na mniejsze części (nazywam je widżetami). Te widżety składają się zasadniczo z pliku MyWidget.hi MyWidget.mpliku, a także MyWidget.xibpliku, w którym elementem głównym jest element a, UIViewa klasa MyWidget jest właścicielem pliku UIView. W inicjalizacji tego widżetu wykonuję plik loadNibNamed.

W moim kontrolerze widoku wykonuję następnie polecenie [[MyWidget alloc] init], które dodaję do widoku głównego kontrolera widoku jako widok podrzędny. Jak dotąd działa to doskonale.

Zastanawiam się teraz, jak zrobić to samo z storyboardem, ponieważ naprawdę nie mogę UIViewgdzieś zacząć przeciągać , zawsze muszę zacząć od tego UIViewController, czego nie chcę.

Jeśli nie ma możliwości zrobienia tego za pomocą Storyboardu, czy mogę po prostu zrobić to w stary sposób, używając Storyboard dla moich głównych ekranów i segue, i użyć oddzielnego pliku .xib do zdefiniowania niestandardowych widoków?

znq
źródło
Czy chcesz tworzyć xibosobne pliki dla kontrolerów widoku, a nie w serii ujęć?
tipycalFlow
Czy znalazłeś rozwiązanie tego problemu?
aryaxt
@aryaxt: Używam mieszanki Storyboard i XIB. Storyboard dla głównych ekranów i xib z tylko UIView jako rootem dla złożonych widoków lub widżetów. Więc nie jest to odpowiedź na moje pierwotne pytanie (przy użyciu storyboardu), ale w zasadzie robię to samo, co robiłem wcześniej.
znq
Te dni, wystarczy użyć widoku kontenera , to naprawdę takie proste .. stackoverflow.com/questions/23399061/...
fattie

Odpowiedzi:

189

Umieszczenie widżetu / widoku w oddzielnym pliku .xib działa i jest odpowiednie, zwłaszcza jeśli chcesz odwoływać się do tego samego widoku z wielu kontrolerów widoku.

Czasami jednak chcesz zobaczyć dodatkowy widok / widżet w tej samej serii ujęć i jest to możliwe. Oto jak to robisz:

  1. Wybierz kontroler widoku w IB (kliknij czarny pasek poniżej widoku), a następnie przeciągnij UIView z biblioteki obiektów na czarny pasek:

    wprowadź opis obrazu tutaj

  2. Gdy widok znajduje się na czarnym pasku, jest tworzony jak każdy inny widok w IB, ale nie jest dodawany do hierarchii widoku, dopóki nie zrobisz tego w kodzie. W razie potrzeby zmień klasę widoku, aby pasowała do Twojej własnej podklasy:

    wprowadź opis obrazu tutaj

  3. Możesz podłączyć go do kontrolera widoku, tak jak podłączasz każdy inny widok: wprowadź opis obrazu tutaj

  4. Dodany widok pojawi się w konspekcie dokumentu i możesz tam również podłączyć akcje i odniesienia:

    wprowadź opis obrazu tutaj


Problem, który pozostaje, polega na tym, że w rzeczywistości nie możesz zobaczyć widoku bez względu na to, ile razy spróbujesz kliknąć lub dwukrotnie kliknąć, co zniweczyłoby cały cel umieszczenia go w tej samej planszy. Na szczęście znam dwa sposoby obejścia tego problemu.

Pierwszym rozwiązaniem jest przeciągnięcie widoku z czarnego paska z powrotem do widoku kontrolera widoku, edytowanie go, a po zakończeniu przeciągnięcie z powrotem do czarnego paska. Jest to kłopotliwe, ale niezawodne.

Drugie obejście jest bardziej skomplikowane, ale wolę je, ponieważ pozwala mi zobaczyć wszystkie moje widoki w tym samym czasie:

  1. Przeciągnij UITableView z biblioteki obiektów do nowo dodanego widoku.

  2. Następnie przeciągnij UITableViewCell do tego UITableView.

    wprowadź opis obrazu tutaj

  3. Gdy to zrobisz, twój widok wyskakuje magicznie z boku, ale masz UITableView, którego nie chcesz. Możesz zmienić rozmiar tego na 0x0 lub możesz go usunąć, a Twój UIView (zwykle) nadal będzie widoczny.

  4. Czasami widok wtórny będzie ponownie ukrywany w IB. Możesz powtórzyć powyższe kroki, jeśli usunąłeś UITableView lub jeśli UITableView nadal znajduje się w hierarchii, wystarczy kliknąć UITableViewCell, a widok pojawi się ponownie.

Druga metoda działa dla UIViews, ale nie tak dobrze dla UIToolbars i jest niemożliwa dla UIButtons, więc najczystszym rozwiązaniem, jakie znalazłem, gdy trzeba uwzględnić wiele różnych podglądów podrzędnych, jest dołączenie pojedynczego pomocniczego UIView do kontrolera widoku jako kontenera, który nigdy nie jest pokazywany, umieść tam wszystkie swoje widoki dodatkowe i użyj sztuczki UITableViewCell, aby wszystko było widoczne. Zmieniam rozmiar mojego atrapy UITableView na 0x0, aby uczynić go niewidocznym. Oto zrzut ekranu pokazujący, jak to wszystko wygląda razem:

wprowadź opis obrazu tutaj

nioq
źródło
Marzec 2013, nie musiałem tego robić - powinieneś całkowicie zignorować czarny pasek i przeciągnąć / upuścić swój widok bezpośrednio do widoku głównego, i działa dobrze (Xcode 4.5+)
Adam
Czy możliwe jest ponowne użycie tego niestandardowego uivew na tym samym ViewController - Jeśli ex. potrzebne dwa niestandardowe uivews - A jeśli tak?
Morten Gustafsson,
2
Cholera, wolę po prostu stworzyć osobny xib. Pewnie tego wszystkiego nie zapamiętam, gdy za 6 miesięcy będę musiał zaktualizować aplikację.
Sandy
Chociaż jest to niesamowita odpowiedź, przypadkowo znalazłem inny lepszy sposób. Podczas podłączania wylotów do rzeczywistych komponentów widoku. Jeśli lekko najedziesz kursorem na element takiego widoku wewnętrznego - wyskakuje on dla łatwiejszego wyboru. Potem widzisz to na scenorysie ...
Oded Ben Dov
7
Chociaż jest to niezwykle godna podziwu historyczna odpowiedź, tak naprawdę jest teraz całkowicie nieaktualna. Apple rozwiązało cały problem, wprowadzając „widoki kontenerów”, które są teraz centralną, podstawową czynnością podczas tworzenia aplikacji - wszystko to przez cały czas w „widoku kontenera”. Dzięki Bogu, teraz jest to bardzo proste!
Fattie
11

Jeśli chcesz, aby twoje kontrolery widoku były inne (a nie na twojej tablicy scenariuszy), jest to całkiem prosty sposób:

1) Utwórz swoje CustomViewControlleradresy ( abcdControllerw kodzie, który próbowałem) z ich indywidualnymi xibadresami, jak zwykle.

2) Dodaj UIViewController(lub cokolwiek było twoją superklasą CustomViewController) do planszy.

3) Ustaw CustomClass CustomViewControllerzamiast, UIViewControllerjak pokazano tutaj:

wprowadź opis obrazu tutaj

4) Na koniec viewDidLoadwczytaj niestandardowy xibi gotowe.

- (void)viewDidLoad
{
    [super viewDidLoad];
    [[NSBundle mainBundle] loadNibNamed:@"abcdController" owner:self options:nil];
    // Do any additional setup after loading the view from its nib.
}
tipycalFlow
źródło
3
Dziękuję za bardzo szczegółową odpowiedź, ale tak naprawdę nie szukam niestandardowego kontrolera widoku, ale niestandardowego widoku (widżetu), który zostanie dodany do standardowego UIViewController. Więc kontroler widoku nie jest problemem, ale zastanawiałem się, jakie jest najlepsze podejście do tworzenia niestandardowych widżetów. Albo A) zrób to tak jak wcześniej, z plikiem .xib lub B) inne podejście, którego jeszcze nie znam :-)
znq
1
Hmm ... Myślę, że mam to, czego chcesz. Zasadniczo chcesz obsługiwać wiele widoków za pomocą tego samego kontrolera, prawda? Nie mogę wymyślić innego sposobu niż loadNibNamedw tym przypadku ... XO
tipycalFlow
To rozwiązało ten problem dla mnie: stackoverflow.com/questions/11047991/… Jednak zamiast viewDidLoad użyłem loadView ...
Morkrom
1
Powtarzam, to wszystko (dzięki Bogu!) Jest całkowicie nieaktualne teraz, gdy są tutaj widoki kontenerów. Po prostu kliknij widok kontenera i gotowe
Fattie,
1

Myślę, że możesz zrobić coś takiego, aby uzyskać wystąpienie określonego kontrolera widoku ze Storyboard i użyć widoku na nim.

ex:
MyViewController* myViewController = [[UIStoryboard storyboardWithName:@"Main"  bundle:nil] instantiateViewControllerWithIdentifier:@"myViewController"];
UIView* view = myViewController.view; //Get the view from your StoryBoard.

Mam nadzieję że to pomoże

Dzięki Vijay

vijay_hrd
źródło