Gdzie określić rozmiar UIView

Podsumowanie: jak UIViewController powinna znać rozmiar swojej instancji UIView podczas inicjalizacji tego widoku?

Dedykowaną metodą inicjalizacji dla UIView jest Metoda initWithFrame:(CGRect)frame. To ustawia ramkę dla nowo utworzonego UIView. Metoda ta może być wywołana z metody loadView UIViewController's, jeśli wymagany jest widok kontrolera widoku. Dokumentacja Stanów UIViewController w odniesieniu do podklasowania i rozmiaru widoku:

Podczas tworzenia widoków dla Twojego widoku hierarchia, ty powinien zawsze ustawić autoresistowskie właściwości Twoich widoków. Gdy kontroler widoku jest wyświetlany na ekran, jego widok główny jest zazwyczaj zmiana rozmiaru w celu dopasowania dostępnej przestrzeni, które mogą się różnić w zależności od bieżąca orientacja okna i obecność innych elementów interfejsu takich jak pasek stanu.

Zatem instancja UIViewController powinna ustawić te właściwości. Do tej pory tak dobrze, UIViewController do tej pory nie musi wiedzieć, jak duży jest lub będzie jego widok.

Gdy view of a UIViewController jest wymagane i właściwość view jest zerowa, wywołana jest metoda loadView kontrolera widoku. Teraz jest problem, ponieważ UIView musi zostać zainicjowany, ale kontroler widoku nadal nie wie, jaki rozmiar powinien mieć widok. Jak duży należy zainicjować ten widok? Gdzie w kodzie określasz rozmiar widoku?

Można zainicjować widok z zerowym rect (CGRectZero):

- (void)loadView {
    self.view = [[[UIView alloc] initWithFrame:CGRectZero] autorelease];
}

I niech rozmówca ustawi ramkę widoku jak więc:

UIViewController *viewController = [[MyUIViewController alloc] init];
// next two lines are normally combined, but for clarity they are not now
UIView *view = viewController.view;
view.frame = CGRectMake(0, 0, 200, 200);

To żądanie widoku z kontrolera widoku (viewController.widok), a tym samym ładuje jego widok metodą loadView. Ta metoda loadView inicjalizuje Widok za pomocą CGRectZero. Następnie wywołujący ustawia swoją ramkę (view.frame = ...)

Rzecz w tym, że właściwość frame w widoku jest ustawiona dwukrotnie, co może powodować jeszcze więcej podwójnej pracy, jeśli twoja niestandardowa UIView wykonuje jakiś zaawansowany układ w metodzie setFrame (np. umieszczanie i zmiana rozmiaru podwidywań). Mógłbyś aby temu zapobiec, należy utworzyć dedykowaną metodę inicjalizacji dla UIViewController, która już prosi wywołującego o CGRect, który przechowywałbyś w ivar. W momencie wywołania metody loadView, można użyć tego ivar do utworzenia widoku.

Jaki jest dobry sposób, aby przejść tutaj? Albo dwukrotne ustawienie ramki widoku (inicjalizacja za pomocą CGRectZero i ustawienie później), albo nadanie UIViewController nowej metody inicjalizacji za pomocą CGRect (i tym samym nadanie jej właściwości frame)? A może czegoś mi brakuje i są są inne możliwości?

Author: Ravi Gautam, 2009-07-09

3 answers

Nie musisz używać wyznaczonego inicjalizatora. Wystarczy użyć init jak w [[UIView alloc] init]. Wyznaczony inicjalizator musi być użyty z inicjalizatorów podklas.

Z drugiej strony, dwukrotne ustawienie ramy nie powinno zaszkodzić. Wykonywanie wielu zadań w {[1] } jest nietypowe. Layouting jest zwykle wykonywany w layoutSubviews i jest wykonywany tylko raz.

 8
Author: Nikolai Ruhe,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-07-09 11:35:11

Obecnie próbuję wykonać to samo po podklasowaniu z UIViewController, aby utworzyć komponent generyczny i zauważyłem coś dziwnego:

UIViewController ma metodę "loadView", którą możesz zastąpić (cytując dokumentację) "to jest miejsce, w którym podklasy powinny tworzyć własną hierarchię widoków".

Tak więc, tworzę swoją hierarchię widoków, składając ekran przy użyciu domyślnego rozmiaru ramki (ponieważ mogę nie znać ramki, powinienem wyświetlać rzeczy w momencie wywołania loadView).

Ale na jakie wezwanie prawidłowo ustawić rozmiary ramek ? Aka: w jakim czasie mój kontroler widoku jest świadomy jego rzeczywistego rozmiaru?

Czy muszę utworzyć "setFrame" w podklasie ViewController, którą powinien wywołać obiekt tworzący viewcontroller ? to wydaje się dziwne.

Drvdijk: czy masz rozwiązanie swojego problemu ?

EDIT: właśnie znalazłem tę notatkę w dokumentacji UIViewController : Uwaga: nie należy używać widoku Kontrolery do zarządzania widokami, które wypełniają tylko część swojego okna-czyli tylko część obszaru zdefiniowanego przez prostokąt zawartości aplikacji. Jeśli chcesz mieć interfejs składający się z kilku mniejszych widoków, Osadź je wszystkie w jednym widoku głównym i zarządzaj tym widokiem za pomocą kontrolera widoku.

Wygląda więc na to, że główny widok UIViewController jest zawsze Pełny ekran. Kropka.

To jednak stanowi dla mnie problem, ponieważ próbuję stworzyć niestandardowy Kontroler Uitabbarview (aby być możliwość wyświetlania własnych obrazków na pasku kart, a nie na niebieskim gradiencie): my tabBarViewController powinien wyświetlać tylko subviewcontrollery w części okna...

 0
Author: Ben G,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-12-23 18:12:35

Możesz obliczyć granice dostępnej przestrzeni ekranu (która zależy od obecności innych widoków, takich jak pasek nawigacji, pasek kart i pasek stanu). Możesz użyć tych ograniczeń dla parametru frame w [[UIView alloc] initWithFrame:] w loadView.

Jeśli tego chcesz, moja odpowiedź może okazać się pomocna: Określ prawidłowy rozmiar w loadView

 0
Author: Tafkadasoh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:24:14