2012-05-24 16 views
10

Tengo algunas propiedades de apariencia personalizada en mi clase de vista (un descendiente de UIView). Quiero personalizar la apariencia vista de acuerdo con estas propiedades, pero no puedo hacer eso dentro de la inicialización, ya que los valores ajustados con [[MyClass appearance] setFoo:…] no están en vigor en ese momento:¿Cuándo puedo comenzar a usar las propiedades establecidas usando 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 

Ya se establecen en layoutSubviews, pero ese no es un buen punto para realizar las personalizaciones de vista, ya que algunas personalizaciones pueden disparar layoutSubviews nuevamente, lo que lleva a un bucle infinito.

Entonces, ¿cuál es un buen punto para realizar las personalizaciones? ¿O hay una forma de activar el código que aplica los valores de apariencia?

+0

Creo que una vez que se ha asignado la clase personalizada, siempre se puede acceder y modificar las propiedades del miembro según los requisitos y luego se puede usar el objeto con la información modificada en el código. –

+1

Solo para asegurarme, estoy hablando de las propiedades establecidas a través del proxy de apariencia ('UIAppearance'). Estos valores se establecen más adelante que en el inicializador. Si configuro un punto de interrupción en el conjunto de propiedades, puedo ver que los valores se aplican desde '[CALayer layoutSublayers] '. – zoul

Respuesta

2

Una posible solución es tomar el valor directamente desde el proxy:

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

Por supuesto, esto mata a la opción de variar la apariencia de acuerdo con el contenedor de vista y es generalmente feo. La segunda opción que encontré es llevar a cabo las personalizaciones en la incubadora:

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

Todavía prefiero tener un poco de gancho que es llamada después de que las propiedades de apariencia se establecen.

+0

ver mi respuesta; el 'gancho' es UIView didMoveToSuperview :, creo. – TomSwift

1

Por qué no esperar hasta que

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

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

si le está dando problemas?

+2

Ese fue mi próximo intento, pero los valores tampoco están establecidos en ese punto. – zoul

0

Hubiera pensado que viewDidLoad sería mejor si se tratara de algo único. De lo contrario, viewWillAppear.

EDIT:

Si desea hacerlo en la vista, y no la del controlador entonces me gustaría crear un inicio personalizada para la vista a lo largo de las líneas de:

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

que pasan de esta manera el color en la vista en el momento de la creación.

+0

Estos son métodos de controlador y prefiero manejarlo en la vista.Además, es bastante probable que los valores no estén configurados aún durante estas llamadas. – zoul

+0

Pasar el color en el inicializador tampoco es una opción, ya que hay más propiedades de apariencia para configurar y el inicializador se llama en un lugar fuera del controlador ... erm, * control *. Se podría decir que el objetivo de la API de proxy de aparición era deshacerse de establecer los valores a mano todo el tiempo. – zoul

+0

Veo de dónde vienes. ¿Tal vez podría crear un método para establecer las propiedades de apariencia y llamarlo en respuesta a una NSNotification (enviada cuando se especifican las propiedades de apariencia)? – ader

0

Creo que las propiedades UIAppearance se aplican a una vista cuando se agrega a una jerarquía de vista. Entonces, presumiblemente, podría acceder a las propiedades establecidas en UIView didMoveToSuperview.

1

Advertencia: Estoy usando Swift 2, por lo que no estoy seguro acerca de las versiones anteriores de Swift/Objective-C. Pero he encontrado que didMoveToSuperview() no funcionará. Las propiedades están disponibles en layoutSubviews(), pero ese no es un buen lugar para hacer algo como esto (ya que se puede llamar más de una vez). El mejor lugar para acceder a estas propiedades en la vidaCiclo de la vista que he encontrado es didMoveToWindow().

Cuestiones relacionadas