11

我想使用容器视图来包含相机预览。我希望相机居中并保持适当的纵横比。(它是粉红色的,以使其框架在哪里很明显)

显示容器视图的故事板

我被困在试图让相机预览以小于容器的尺寸出现的第一步。

我有一个用于相机控制器视图的 UIView 子类,并且有代码:

- (CGSize)intrinsicContentSize
{
  return CGSizeMake(320, 240);
}

不幸的是,这没有得到尊重:

iPad模拟器结果

通过阅读文档,intrinsicContentSize看起来这就是我想要的。最终我也想使用自动布局,但我试图一次解决一件事。

我该如何进行这项工作?

4

2 回答 2

22

自动布局使用该intrinsicContentSize属性。如果您不使用自动布局,系统将不会要求任何视图为其intrinsicContentSize.

除非您编写一些代码,否则粉红色视图将被强制为容器视图的大小。无论您是否使用自动布局,这都是正确的。这正是在故事板中创建的容器视图的工作方式。系统不会询问您的粉色视图intrinsicContentSize

由于您暗示您没有使用自动布局,因此您可以通过以下一种方法使容器视图成为intrinsicContentSize其内容视图的一部分。UIView创建一个被调用的子类CameraContainerView并将其设置为容器视图的自定义类。addSubview:在这个新类中覆盖:

@implementation CameraContainerView

- (void)addSubview:(UIView *)subview {
    [super addSubview:subview];
    CGRect frame = self.frame;
    frame.size = subview.intrinsicContentSize;
    self.frame = frame;
}

@end

这在我的测试中就足够了。(如果子视图动态更改,它将不会保持最新intrinsicContentSize。)

如果决定使用自动布局,则需要在容器视图和内容视图之间设置约束,并且需要删除任何冲突的约束。

首先,在您的故事板中,确保容器视图具有明确的宽度和高度约束。(这些约束将被删除,因此它们的确切大小无关紧要。)CameraContainerView为这些约束中的每一个提供一个出口:

@interface CameraContainerView ()

@property (nonatomic, strong) IBOutlet NSLayoutConstraint *widthConstraint;
@property (nonatomic, strong) IBOutlet NSLayoutConstraint *heightConstraint;

@end

将这些出口连接到情节提要中的约束。请注意,这些插座是 on CameraContainerView而不是on ViewController,所以不要尝试从视图控制器控制拖动到约束;那是行不通的。

还要确保容器视图没有固定到其父视图的左右(前导和后导)边缘,并且它没有固定到其父视图的顶部和底部。容器视图的大小仅由其明确的宽度和高度约束决定,这一点很重要。

在情节提要中设置约束并连接出口后,您可以重写addSubview:自动布局。您需要关闭translatesAutoresizingMaskIntoConstraints嵌入式视图:

@implementation CameraContainerView

- (void)addSubview:(UIView *)subview {
    subview.translatesAutoresizingMaskIntoConstraints = NO;

    [super addSubview:subview];

然后您需要删除从情节提要中加载的宽度和高度约束:

    [self removeConstraint:self.widthConstraint];
    self.widthConstraint = nil;
    [self removeConstraint:self.heightConstraint];
    self.heightConstraint = nil;

最后,您可以设置新的约束,将嵌入视图定位在容器视图中,并使容器视图与嵌入视图的大小相匹配:

    NSDictionary *views = NSDictionaryOfVariableBindings(subview);
    [self addConstraints:[NSLayoutConstraint
        constraintsWithVisualFormat:@"H:|[subview]|"
        options:0 metrics:nil views:views]];
    [self addConstraints:[NSLayoutConstraint
        constraintsWithVisualFormat:@"V:|[subview]|"
        options:0 metrics:nil views:views]];
}

@end

这在我的测试中有效,并且如果子视图intrinsicContentSize动态更改它应该保持最新,只要子视图发送自己invalidateIntrinsicContentSize

于 2013-06-29T04:10:59.403 回答
0

我在 Interface Builder 中发现了错误。在它的帮助下,您可以使用intrinsicContentSize 添加自定义视图。

1) 在界面生成器的视图上添加 UIButton。我设置了 centerY 和 centerX 约束。此按钮是您的自定义视图。 在此处输入图像描述

2)将您的自定义视图替换为 UIButton 的超类:

@interface CustomView : UIView
@end

@interface CustomView : UIButton
@end

3)在情节提要中设置类 UIButton :

在此处输入图像描述

4)返回超类您的自定义视图:

@interface CustomView : UIView
@end

5) 运行。我的 CustomView 在中心屏幕上显示灰色方块 (300х300)。编译没有错误和警告。

@implementation CustomView

- (void)awakeFromNib
{
    [super awakeFromNib];

    self.backgroundColor = [UIColor grayColor];
}

- (CGSize)intrinsicContentSize
{
    return CGSizeMake(300, 300);
}

@end

结果 :

在此处输入图像描述

于 2014-12-14T12:11:02.320 回答