8

根据 UIView 关于该contentMode属性的官方文档:

The content mode specifies how the cached bitmap of the view’s layer is adjusted when the view’s bounds change

这个定义中的内容是什么定义的?例如,它是子视图还是当我们为视图定义了背景颜色时。

我的第一个猜测是,它至少应该适用于视图中的子视图,但例如以下代码片段在使用 UIViewContentModeCenter标签时不会给我预期的结果:

 UIView* redView = [[UIView alloc] initWithFrame:CGRectMake(80, 80, 150, 200)];
 redView.contentMode = UIViewContentModeCenter;
 redView.backgroundColor = [UIColor redColor];

 UIView* greenView = [[UIView alloc] initWithFrame:redView.bounds];
 greenView.backgroundColor = [UIColor greenColor];
 [redView addSubview:greenView];

 redView.frame = CGRectInset(redView.frame, -5, -5);
 [self.view addSubview:redView];

我刚刚设置了一个包含 greenView 的 redView。我还将 redview 的内容模式设置为UIViewContentModeCenter- 为什么在我编写的代码中,当我更改其父级的框架时,greenView 没有居中?不应UIViewContentModeCenter该做什么?

感谢您的澄清!

Ps:loadView你可以在一个简单的视图控制器模板项目中轻松测试上面的代码。

4

2 回答 2

10

从文档中:

内容模式指定当视图的边界发生变化时如何调整视图层的缓存位图。

对于图像视图,这是在谈论图像。对于绘制其内容的视图,这是在谈论绘制的内容。它不影响子视图的布局。

您需要查看子视图上的自动调整大小掩码。内容模式在这里是一个红鲱鱼。如果您无法使用自动调整大小的掩码实现所需的布局,那么您需要实现 layoutSubviews 并手动计算子视图的位置和框架。

来自 jrturton 的回答:https ://stackoverflow.com/a/14111480/1374512

于 2013-03-28T06:27:05.380 回答
5

首先在此处阅读有关内容模式的信息

在您的示例中,您更改了红色视图的框架。这将在视图上调用 layoutSubviews,该视图将根据布局约束或自动调整掩码重新定位绿色视图。你没有指定任何。所以绿色视图的框架将保持不变。

内容模式指定视图层在调整大小时应如何更新。根据内容模式 drawRect 是否会被调用。

您可以通过以下示例测试不同内容模式的效果:

添加一个 UIView 子类,它使用这个 drawRect 实现绘制一个圆:

- (void)drawRect:(CGRect)rect
{
    // Drawing code
    NSLog(@"drawRect %@", NSStringFromCGRect(rect));

    CGContextRef ctx = UIGraphicsGetCurrentContext();
    CGContextAddEllipseInRect(ctx, self.bounds);
    [[UIColor redColor] setFill];
    CGContextFillPath(ctx);
}

在视图控制器中创建并添加圆形视图:

CircleView* circleView = [[CircleView alloc] initWithFrame:CGRectMake(10, 10, 20, 20)];
circleView.contentMode = UIViewContentModeCenter; // <- try different modes here
[self.view addSubview:circleView];

现在让帧动画,看看会发生什么:

dispatch_async(dispatch_get_main_queue(), ^{
    [UIView animateWithDuration:5 animations:^{
        circleView.frame = CGRectMake(10, 10, 100, 200);
    }];
});

我正在异步执行此操作,以强制 CoreGraphics 使用原始帧至少绘制一次视图。当您不设置内容模式时,您最终会得到一个模糊的圆圈,因为它只是按比例放大而无需重绘。UIViewContentModeCenter 使小圆圈保持在中心 - 也不需要重绘。UIViewContentModeRedraw 使视图使用新框架再次绘制视图。实际上,这发生在动画开始之前。

请注意,内容模式会影响绘图性能。

于 2012-10-20T13:18:41.230 回答