2010-04-19 11 views
5

¿Cuál es la mejor manera de posicionar una vista en relación con el tamaño de su supervista, cuando aún no se conocen los límites de la supervista?¿Cómo puedo posicionar una vista mediante programación usando puntos relativos?

Estoy tratando de evitar las coordenadas de codificación difícil, si es posible. Tal vez esto es una tontería, y si es así, esa es una respuesta perfectamente aceptable.

Me he encontrado con esto muchas veces cuando trabajo con una interfaz de usuario personalizada. El ejemplo más reciente es que estoy tratando de reemplazar el título de texto sin formato UINavigationItem con una vista personalizada. Quiero que esa vista llene la supervista, pero además, quiero un UIActivityIndicatorView en el lado derecho, inserte unos 2 píxeles y centrado verticalmente. Aquí está el código:

- (void) viewDidLoad 
{ 
    [super viewDidLoad]; 

    customTitleView = [[UIView alloc] initWithFrame:CGRectZero]; 
    customTitleView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth; 

    titleLabel = [[UILabel alloc] initWithFrame:CGRectZero]; 
    titleLabel.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth; 
    titleLabel.lineBreakMode = UILineBreakModeWordWrap; 
    titleLabel.numberOfLines = 2; 
    titleLabel.minimumFontSize = 11.0; 
    titleLabel.font = [UIFont systemFontOfSize:17.0]; 
    titleLabel.adjustsFontSizeToFitWidth = YES; 
    [customTitleView addSubview:titleLabel]; 

    spinnerView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite]; 
    spinnerView.center = CGPointMake(customTitleView.bounds.size.width - (spinnerView.bounds.size.width/2) - 2, 
            customTitleView.bounds.size.height/2); 
    spinnerView.hidesWhenStopped = YES; 
    [customTitleView addSubview:spinnerView]; 

    self.navigationItem.titleView = customTitleView; 
    [customTitleView release]; 
} 

aquí es mi problema: en el momento en que este código se ejecuta, customTitleView.bounds sigue siendo ceros. La máscara de cambio de tamaño automático no ha tenido la oportunidad de hacer esto todavía, pero realmente quiero esos valores para que pueda calcular las posiciones relativas de otras sub-vistas (aquí, el indicador de actividad).

¿Esto es posible sin ser feo?

+0

'' titleLabel' y spinnerView' son ambos objetos filtrados –

+0

1 para la pregunta ya que tengo exactamente el mismo - con ganas de leer las respuestas – Till

+1

'titleLabel' y' spinnerView' no se filtraron. Se lanzan a otra parte. –

Respuesta

4

El único motivo por el que customTitleView.bounds tiene ancho y alto cero es porque lo ha inicializado de esa manera con CGRectZero. Puede inicializar la vista con cualquier tamaño distinto de cero y luego definir sus subvistas en relación con ese tamaño arbitrario. Siempre que haya definido correctamente los comportamientos de ajuste automático de las subvistas, su diseño se ajustará adecuadamente cuando el marco de la supervista cambie en tiempo de ejecución.

Por ejemplo:

- (void) viewDidLoad 
{ 
    [super viewDidLoad]; 

    customTitleView = [[UIView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 100.0f, 100.0f)]; 
    customTitleView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth; 

    titleLabel = [[UILabel alloc] initWithFrame:customTitleView.bounds]; 
    titleLabel.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth; 
    titleLabel.lineBreakMode = UILineBreakModeWordWrap; 
    titleLabel.numberOfLines = 2; 
    titleLabel.minimumFontSize = 11.0; 
    titleLabel.font = [UIFont systemFontOfSize:17.0]; 
    titleLabel.adjustsFontSizeToFitWidth = YES; 
    [customTitleView addSubview:titleLabel]; 
    [titleLabel release]; 

    spinnerView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite]; 
    spinnerView.center = CGPointMake(customTitleView.bounds.size.width - (spinnerView.bounds.size.width/2) - 2, 
            customTitleView.bounds.size.height/2); 
    spinnerView.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin; 
    spinnerView.hidesWhenStopped = YES; 
    [customTitleView addSubview:spinnerView]; 
    [spinnerView release]; 

    self.navigationItem.titleView = customTitleView; 
    [customTitleView release]; 
} 
+1

Gracias. Me faltaban dos puntos clave. En primer lugar, la vista que lo contiene necesita cierto tamaño, presumiblemente para que el comportamiento del diseño pueda tomar decisiones sensatas. En segundo lugar, la ruleta no configuró su 'autoresizingMask' para usar los márgenes (arriba, abajo e izquierda para hacer que se pegue al lado derecho). –

Cuestiones relacionadas