iOS容器视图不尊重intrinsicContentSize
我想使用容器视图来包含相机预览。 我想让相机居中,保持适当的宽高比。 (这是粉红色的,使其明显的地方在哪里)
我被困在试图让相机预览出现在比容器小的尺寸上的第一步。
我有一个相机控制器的视图的UIView子类,并有代码:
- (CGSize)intrinsicContentSize { return CGSizeMake(320, 240); }
不幸的是,这不是荣幸:
从阅读文档, intrinsicContentSize
看起来就是我想要的。 最终我也想使用自动布局,但我试图一次解决一件事。
我该如何做这项工作?
自动布局使用intrinsicContentSize
属性。 如果您没有使用自动布局,系统将不会询问其intrinsicContentSize
任何视图。
粉红色视图将被强制为容器视图的大小,除非您编写一些代码。 无论您是否使用自动布局,情况都是如此。 这只是容器视图在故事板工作中创build的方式。 系统不会问你的粉红色视图的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
这在我的testing中已经足够了。 (如果子视图dynamic地改变其intrinsicContentSize
它不会保持最新。)
如果您决定使用自动布局,则需要在容器视图和内容视图之间设置约束,并且需要删除任何冲突的约束。
首先,在故事板中,确保容器视图具有明确的宽度和高度限制。 (这些约束将被删除,所以它们的确切大小无关紧要。)为CameraContainerView
提供这些约束的出口:
@interface CameraContainerView () @property (nonatomic, strong) IBOutlet NSLayoutConstraint *widthConstraint; @property (nonatomic, strong) IBOutlet NSLayoutConstraint *heightConstraint; @end
将这些sockets连接到故事板中的约束条件。 请注意,这些sockets在CameraContainerView
, 而不是在ViewController
,所以不要试图从视图控制器拖拽到约束条件; 那不行。
另外,请确保容器视图不会固定在其超级视图的左侧和右侧(前导和尾随)边缘,也不会固定到其超级视图的顶部和底部。 容器视图的大小仅由其明确的宽度和高度约束来确定是很重要的。
在故事板中设置约束条件并连接sockets之后,可以重写addSubview:
以进行自动布局。 您需要closuresembedded式视图上的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;
最后,您可以设置新的约束,将embedded式视图放置在容器视图中,并使容器视图与embedded式视图的大小相匹配:
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
这工作在我的testing,并应保持最新,如果子视图dynamic更改其intrinsicContentSize
,只要子视图发送自己invalidateIntrinsicContentSize
。
我发现在界面生成器中的错误。 在它的帮助下,您可以使用intrinsicContentSize添加自定义视图。
1)在界面生成器中的视图添加UIButton。 我设置了centerY和centerX约束。 这个button是你的自定义视图。
2)将您的自定义视图replace为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
结果: