【问题标题】:What type of contents UIViewContentMode mode refers to?UIViewContentMode 模式指的是什么类型的内容?
【发布时间】:2012-10-10 20:22:55
【问题描述】:

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

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

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

我的第一个猜测是,它至少应该适用于视图中的子视图,但例如以下代码 sn-p 在使用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中轻松测试上述代码。

【问题讨论】:

  • 肯定通过调整框架,您将重绘包含设置为正在更改的框架边界的子视图的视图?因此它不会保持居中,因为边界是相对于框架的?用简单的英语使用边界作为框架,您的原点始终为 0,0 并且匹配的宽度和高度

标签: ios5 uiview contentmode uiview-hierarchy


【解决方案1】:

来自文档:

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

对于图像视图,这是在谈论图像。为了一个观点 绘制它的内容,这里说的是绘制的内容。它确实 不影响子视图的布局。

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

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

【讨论】:

    【解决方案2】:

    首先了解内容模式 here

    在您的示例中,您更改了红色视图的框架。这将在视图上调用 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 使视图使用新框架再次绘制视图。实际上这发生在动画开始之前。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-05-25
      • 2010-10-03
      • 2015-08-10
      • 1970-01-01
      • 1970-01-01
      • 2013-09-05
      相关资源
      最近更新 更多