iOS容器视图不支持intrinsicContentSize

时间:2013-06-29 02:53:52

标签: ios objective-c uikit uistoryboard autolayout

我想使用容器视图来包含相机预览。我希望相机在中间居中并保持适当的宽高比。 (它的粉红色使其框架显而易见)

Story board showing container view

我坚持第一步,试图让相机预览显示的尺寸小于容器。

我有一个用于Camera Controller视图的UIView子类,并且有代码:

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

不幸的是,这并不值得尊重:

iPad simulator result

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

我如何使这项工作?

2 个答案:

答案 0 :(得分:17)

自动布局使用intrinsicContentSize属性。如果您没有使用自动布局,系统将不会询问任何视图intrinsicContentSize

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

由于您暗示您使用自动布局,因此您可以通过以下方式将容器视图作为其内容视图的intrinsicContentSize。创建一个名为UIView的{​​{1}}的子类,并将其设置为容器视图的自定义类。覆盖此新类中的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 上的CameraContainerView而不是,因此请勿尝试从视图控制器控制拖动到约束;这是行不通的。

还要确保容器视图不固定到其超视图的左右两边(前端和后端)边缘,并且不会固定到其超视图的顶部和底部。重要的是容器视图的大小只能由其明确的宽度和高度约束来确定。

在故事板中设置约束并连接出口后,您可以重写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

答案 1 :(得分:0)

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

1)在Interface Builder中的View上添加UIButton。我设置了centerY和centerX约束。此按钮是您的自定义视图。 enter image description here

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

@interface CustomView : UIView
@end

@interface CustomView : UIButton
@end

3)在故事板中设置类UIButton:

enter image description here

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

结果:

enter image description here