2012-05-24 11 views
10

Mam pewne niestandardowe właściwości wyglądu w mojej klasie widoku (potomek UIView). Chcę dostosować wygląd widok według tych właściwości, ale nie mogę tego zrobić wewnątrz inicjatora, ponieważ wartości ustawiane za pomocą [[MyClass appearance] setFoo:…] nie są w istocie w tym punkcie:Kiedy mogę zacząć korzystać z właściwości ustawionych za pomocą UIAppearance?

@interface View : UIView 
@property(strong) UIColor *someColor UI_APPEARANCE_SELECTOR; 
@end 

@implementation View 
@synthesize someColor; 

// Somewhere in other code before the initializer is called: 
// [[View appearance] setSomeColor:[UIColor blackColor]]; 

- (id) initWithFrame: (CGRect) frame 
{ 
    self = [super initWithFrame:frame]; 
    NSLog(@"%@", someColor); // nil 
    return self; 
} 

@end 

już są ustawione w layoutSubviews, ale nie jest to dobry punkt do wykonywania dostosowań widoku, ponieważ niektóre dostosowania mogą ponownie uruchomić layoutSubviews, prowadząc do nieskończonej pętli.

Jaki jest dobry punkt do przeprowadzenia dostosowań? Czy istnieje sposób wyzwalania kodu, który stosuje wartości wyglądu?

+0

myślę raz klasa zwyczaj została przydzielona, ​​właściwości członka może być zawsze dostępny i zmieniane zgodnie z wymaganiami, a następnie obiekt może być używany ze zmodyfikowanym informacji zawartych w kodzie. –

+1

Tylko po to, aby się upewnić, że mówię o właściwościach ustawionych przez serwer proxy wyglądu ('UIAppearance'). Wartości te są ustawiane gdzieś później niż w inicjalizatorze. Jeśli ustawię punkt przerwania na selektorze właściwości, widzę, że wartości są stosowane od '[CALayer layoutSublayers]'. – zoul

Odpowiedz

2

Możliwym rozwiązaniem jest pobrać wartość bezpośrednio z Proxy:

- (id) initWithFrame: (CGRect) frame 
{ 
    self = [super initWithFrame:frame]; 
    NSLog(@"%@", [[View appearance] someColor); // not nil 
    return self; 
} 

Oczywiście zabija opcję do zmiany wyglądu w przypadku pojemnika widzenia i zasadniczo brzydkie. Druga opcja znalazłem jest do wykonywania dostosowań w seter:

- (void) setSomeColor: (UIColor*) newColor 
{ 
    someColor = newColor; 
    // do whatever is needed 
} 

Wciąż wolałbym mieć jakiś haczyk, który jest wywoływana po właściwości wyglądu są ustawione.

+0

zobacz moją odpowiedź; "hook" to UIView didMoveToSuperview :, wierzę. – TomSwift

1

Dlaczego nie czekać aż

- (void)willMoveToSuperview:(UIView *)newSuperview { 
    [super willMoveToSuperview:newSuperview]; 

    if (newSuperview) { 
     ... code here ... 
    } 
} 

jeśli to daje kłopoty?

+2

To była moja następna próba, ale wartości również nie są ustawione w tym punkcie. – zoul

0

Myślę, że viewDidLoad byłby najlepszy, jeśli jest to jednorazowa rzecz. W przeciwnym razie viewWillAppear.

EDIT:

Jeśli chcesz to zrobić w widoku, a nie jest to kontroler wtedy utworzyć niestandardowe metody init dla widoku wzdłuż linii:

-(id) initWithFrame:(CGRect) frame andAppearanceColor:(UIColor)theColor; 

co przechodzących kolor do widoku w czasie tworzenia.

+0

To są metody kontrolerów i wolałbym je obsłużyć w widoku.Poza tym jest całkiem prawdopodobne, że wartości nie są ustawione podczas tych połączeń. – zoul

+0

Przekazywanie koloru w inicjalizatorze również nie jest opcją, ponieważ istnieje więcej właściwości wyglądu, które można ustawić, a inicjator jest wywoływany w miejscu poza kontrolerem ... erm, * kontrola *. Można powiedzieć, że cały punkt API proxy pojawiania się miał na celu pozbycie się ręcznego ustawiania wartości przez cały czas. – zoul

+0

Widzę, skąd przybywasz. Może mógłbyś stworzyć metodę ustawiania właściwości wyglądu i wywoływać go w odpowiedzi na NSNotification (wysyłane, gdy określone są właściwości wyglądu)? – ader

0

Wierzę, że właściwości UIAppearance są stosowane do widoku, gdy jest on dodawany do hierarchii widoków. Prawdopodobnie możesz uzyskać dostęp do ustawionych właściwości w UIView didMoveToSuperview.

1

Zastrzeżenie: używam Swift 2, więc nie jestem pewien co do wcześniejszych wersji Swift/Objective-C. Ale stwierdziłem, że didMoveToSuperview() nie będzie działać. Właściwości są dostępne pod adresem layoutSubviews(), ale nie jest to świetne miejsce do robienia czegoś podobnego (ponieważ można go wywołać więcej niż raz). Najlepszym miejscem dostępu do tych właściwości w cyklu życia widoku, który znalazłem, jest didMoveToWindow().

Powiązane problemy