从数组中获取 CGRect

Posted

技术标签:

【中文标题】从数组中获取 CGRect【英文标题】:Getting CGRect from array 【发布时间】:2011-03-25 11:03:14 【问题描述】:

对于我的应用程序,我试图将 CGRect 对象存储到 NSMutableArray 中。它加载良好并在日志语句中打印,但尝试从数组中获取 CGRects 会显示错误。这是一个代码sn-p:

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

  [lineRactangle addObject:NSStringFromCGRect(lineRact)];

如何从数组中取回矩形?

【问题讨论】:

【参考方案1】:

CGRect 是一个结构体,而不是一个对象,因此不能存储在 NSArrays 或 NSDictionaries 中。你可以把它变成一个字符串,然后把那个字符串变成一个CGRect,但是最好的方法是通过一个NSValue来封装它:

NSValue *myValue = [NSValue valueWithCGRect:myCGRect];

然后您可以将此 NSValue 对象存储在数组和字典中。要将其转回 CGRect,您可以:

CGRect myOtherCGRect = [myValue CGRectValue];

【讨论】:

或今天,NSValue *myValue = [NSValue valueWithRect:myCGRect]; @FitterMan:这仅适用于 OS X,不适用于 iosvalueWithRect: 在 iOS 上不可用。但即使在 OS X 上,您也不应该这样做:valueWithRect: 需要 NSRect,而不是 CGRect。在 64 位构建中,NSRectCGRect 的 typedef,因此它可以在那里正常工作,但对于没有将 NS_BUILD_32_LIKE_64 定义设置为 1 的 32 位构建,您将收到警告/错误因为它们在那里被定义为两个独立的结构。尽管它们的内存表示是相同的,但编译器(正确地)将它们视为两个不同的东西。 感谢您的澄清。【参考方案2】:
[lineRactangle addObject:[NSValue valueWithCGRect:lineRect]];

【讨论】:

【参考方案3】:

使用NSValue 包装CGRect 从而将它们存储在NSArrays 中。

例如:

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

有关其他支持的结构,请参阅 documentation。

【讨论】:

【参考方案4】:

实际上,我认为迄今为止的任何答案都没有真正解决 ajay 提出的问题。简短的回答是:您需要为 CGRectMake 提供 intValue,而不是字典项的 floatValue。如果您需要对多个 CGRect 执行此操作,这里有一个建议的方法:

- (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]);

可能有更优雅的方式来实现这一点,但上面的代码确实有效。

【讨论】:

【参考方案5】:

如果您的对象可以使用“.frame”设置,您可以使用:

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

或者对于多个对象:

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]);

【讨论】:

【参考方案6】:

CGRect 是一个结构,你不能把它放在一个 NSArray 中。您只能向其中添加对象。

【讨论】:

【参考方案7】:

或更“极端”的东西...创建一个包含 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];

其中 'GridAA'、'GridAB' 等对应于 UIViews

【讨论】:

本附录最好作为评论添加到所引用的答案中,因为人们无法将其视为解决方案,而且它似乎是评论。

以上是关于从数组中获取 CGRect的主要内容,如果未能解决你的问题,请参考以下文章

检查 CGRect 是不是与 CGRect 数组相交

与更改数组值同步更新 UIView

通过 CGRect Intersects Rect 过滤 ns 可变数组

CGRectIntersectsRect 工作不一致

从数组数组中获取最小的数组

使用 UIPanGestureRecognizer 从 CGRect 获取 UIView - Swift 2.0