2011-03-25 20 views
11

Para mi aplicación, estoy intentando almacenar objetos CGRect en un NSMutableArray. Se está cargando bien y está imprimiendo en la declaración de registro, pero tratando de tomar el CGRect s de la matriz muestra un error. Aquí hay un fragmento de código:Obteniendo CGRect de la matriz

CGRect lineRact = CGRectMake([[attributeDict objectForKey:@"x"] floatValue], 
    [[attributeDict objectForKey:@"y"] floatValue], 
    [[attributeDict objectForKey:@"width"] floatValue], 
    [[attributeDict objectForKey:@"height"] floatValue]); 

    [lineRactangle addObject:NSStringFromCGRect(lineRact)]; 

¿Cómo puedo recuperar las pruebas de la matriz?

Respuesta

22
[lineRactangle addObject:[NSValue valueWithCGRect:lineRect]]; 
+0

gracias por su reproducción anticipada ... – ajay

0

CGRect es una estructura que no puedes poner en un NSArray. Solo puedes agregarle objetos.

40

Un CGRect es una estructura, no un objeto, y por lo tanto no se puede almacenar en NSArrays o NSDictionaries. Puede convertirlo en una cadena y deshabilitar esa cadena de nuevo en un CGRect, pero la mejor manera es encapsular que a través de un NSValue:

NSValue *myValue = [NSValue valueWithCGRect:myCGRect]; 

entonces se puede almacenar este objeto NSValue en matrices y diccionarios. Para convertirla de nuevo en una CGRect, que haría:

CGRect myOtherCGRect = [myValue CGRectValue]; 
+0

o actuales, 'NSValue * myValue = [NSValue valueWithRect: myCGRect ]; ' –

+1

@FitterMan: Esto solo se aplica a OS X, no a iOS; 'valueWithRect:' no está disponible en iOS. Pero incluso en OS X, no debería hacer eso: 'valueWithRect:' espera un 'NSRect', no un' CGRect'. En compilaciones de 64 bits, 'NSRect' es un typedef de' CGRect', por lo que funciona allí sin problemas, pero para las compilaciones de 32 bits sin que la definición 'NS_BUILD_32_LIKE_64' se establezca en' 1', recibirá una advertencia/error ya que están definidos como dos estructuras separadas allí. Aunque su representación de memoria es la misma, el compilador (correctamente) los trata como si fueran dos cosas diferentes allí. – DarkDust

+0

Gracias por aclararnos. –

6

Uso NSValue para envolver CGRect tanto almacenarlos en NSArray s.

Por ejemplo:

CGRect r = CGRectMake(1,2,3,4); 
NSValue *v = [NSValue valueWithCGRect:rect]; 
NSArray *a = [NSArray arrayWithObject:v]; 
CGRect r2 = [[a lastObject] CGRectValue]; 

Ver documentation para las otras estructuras compatibles.

0

o algo más 'extremo' ... la creación de una matriz que contiene las matrices de CGRect (s)

movPosTable = [[NSArray alloc] initWithObjects: 
      [[NSArray alloc] initWithObjects: [NSValue valueWithCGRect:[GridAB frame]], [NSValue valueWithCGRect:[GridBA frame]], [NSValue valueWithCGRect:[GridBB frame]], nil], 
      [[NSArray alloc] initWithObjects: [NSValue valueWithCGRect:[GridAA frame]], [NSValue valueWithCGRect:[GridAC frame]], [NSValue valueWithCGRect:[GridBA frame]], [NSValue valueWithCGRect:[GridBB frame]], [NSValue valueWithCGRect:[GridBC frame]], nil], 
      [[NSArray alloc] initWithObjects: [NSValue valueWithCGRect:[GridAB frame]], [NSValue valueWithCGRect:[GridBB frame]], [NSValue valueWithCGRect:[GridBC frame]], nil], nil]; 

donde 'GridAA', 'GridAB', etc. corresponden a UIViews

+0

Este apéndice debería haberse agregado mejor como comentario a la respuesta referida porque no se podía ver como una solución y parece ser un comentario. – iOS

2

En realidad, No creo que ninguna de las respuestas hasta ahora realmente aborde la pregunta que hizo. La respuesta breve es: Necesita suministrar CGRectMake con intValue, en lugar de floatValue del elemento del diccionario. Si necesita hacer esto durante varios CGRects, aquí hay un método sugerido:

- (CGRect) NSArrayToCGRect: (NSDictionary *) attributeDict 
{ 
    int x = [[attributeDict objectForKey:@"x"] intValue]; 
    int y = [[attributeDict objectForKey:@"y"] intValue]; 
    int w = [[attributeDict objectForKey:@"width"] intValue]; 
    int h = [[attributeDict objectForKey:@"height"] intValue]; 

    return CGRectFromString([NSString stringWithFormat: @"{{%d,%d},{%d,%d}}", x, y, w, h]); 
} 

Puede haber una forma más elegante de lograr esto, pero el código anterior funciona.

2

Si el objeto se puede establecer con ".Frame" se puede utilizar:

// {{CGFloat x,CGFloat y}, {CGFloat width,CGFloat height}} 
NSString *objectCoords = @"{{116,371},{85,42}}"; 
myObject.frame = CGRectFromString(objectcoords); 

o para múltiples objetos:

NSArray *objectCoords = [NSArray arrayWithObjects: 
         @"{{116,371},{85,42}}", 
         @"{{173,43},{85,42}}", 
         @"{{145,200},{85,42}}", 
         nil]; 

myObject1.frame = CGRectFromString([objectCoords objectAtIndex:0]); 
myObject2.frame = CGRectFromString([objectCoords objectAtIndex:1]); 
myObject3.frame = CGRectFromString([objectCoords objectAtIndex:2]); 
Cuestiones relacionadas