如何在 CALayer 中定位内容,使其缩放以适应宽度(保留纵横比)并定位在图层的顶部?
更具体地说,我正在尝试使用 AVCaptureVideoPreviewLayer 来实现此定位。如果我将预览层的 videoGravity 设置为 AVLayerVideoGravityResizeAspectFill ,那么它会填充宽度但将内容垂直居中在框架中(切断顶部和底部)。
如何在 CALayer 中定位内容,使其缩放以适应宽度(保留纵横比)并定位在图层的顶部?
更具体地说,我正在尝试使用 AVCaptureVideoPreviewLayer 来实现此定位。如果我将预览层的 videoGravity 设置为 AVLayerVideoGravityResizeAspectFill ,那么它会填充宽度但将内容垂直居中在框架中(切断顶部和底部)。
尝试使用 .contentGravity 属性 -
一个常量,指定层的内容如何在其边界内定位或缩放
<CALayer>.contentsGravity = kCAGravityResizeAspect;
可能的
CA_EXTERN NSString * const kCAGravityCenter
__OSX_AVAILABLE_STARTING (__MAC_10_5, __IPHONE_2_0);
CA_EXTERN NSString * const kCAGravityTop
__OSX_AVAILABLE_STARTING (__MAC_10_5, __IPHONE_2_0);
CA_EXTERN NSString * const kCAGravityBottom
__OSX_AVAILABLE_STARTING (__MAC_10_5, __IPHONE_2_0);
CA_EXTERN NSString * const kCAGravityLeft
__OSX_AVAILABLE_STARTING (__MAC_10_5, __IPHONE_2_0);
CA_EXTERN NSString * const kCAGravityRight
__OSX_AVAILABLE_STARTING (__MAC_10_5, __IPHONE_2_0);
CA_EXTERN NSString * const kCAGravityTopLeft
__OSX_AVAILABLE_STARTING (__MAC_10_5, __IPHONE_2_0);
CA_EXTERN NSString * const kCAGravityTopRight
__OSX_AVAILABLE_STARTING (__MAC_10_5, __IPHONE_2_0);
CA_EXTERN NSString * const kCAGravityBottomLeft
__OSX_AVAILABLE_STARTING (__MAC_10_5, __IPHONE_2_0);
CA_EXTERN NSString * const kCAGravityBottomRight
__OSX_AVAILABLE_STARTING (__MAC_10_5, __IPHONE_2_0);
CA_EXTERN NSString * const kCAGravityResize
__OSX_AVAILABLE_STARTING (__MAC_10_5, __IPHONE_2_0);
CA_EXTERN NSString * const kCAGravityResizeAspect
__OSX_AVAILABLE_STARTING (__MAC_10_5, __IPHONE_2_0);
CA_EXTERN NSString * const kCAGravityResizeAspectFill
__OSX_AVAILABLE_STARTING (__MAC_10_5, __IPHONE_2_0);
尝试使用这组代码:
将此行添加到图层的初始布局:
[previewLayer setVideoGravity:AVLayerVideoGravityResizeAspectFill];
然后添加这些:
- (void) viewDidLayoutSubviews
{
[self layoutPreviewInView:_photoImageView];
}
-(void)layoutPreviewInView:(UIView *) aView
{
AVCaptureVideoPreviewLayer *layer = [self previewInView:aView];
if (!layer) return;
UIDeviceOrientation orientation = [UIDevice currentDevice].orientation;
CATransform3D transform = CATransform3DIdentity;
if (orientation == UIDeviceOrientationPortrait) ;
else if (orientation == UIDeviceOrientationLandscapeLeft)
transform = CATransform3DMakeRotation(-M_PI_2, 0.0f, 0.0f, 1.0f);
else if (orientation == UIDeviceOrientationLandscapeRight)
transform = CATransform3DMakeRotation(M_PI_2, 0.0f, 0.0f, 1.0f);
else if (orientation == UIDeviceOrientationPortraitUpsideDown)
transform = CATransform3DMakeRotation(M_PI, 0.0f, 0.0f, 1.0f);
layer.transform = transform;
layer.frame = aView.bounds;
}
-(AVCaptureVideoPreviewLayer *) previewInView: (UIView *) view
{
for (CALayer *layer in view.layer.sublayers)
{
if ([layer isKindOfClass:[AVCaptureVideoPreviewLayer class]])
return (AVCaptureVideoPreviewLayer *) layer;
}
return nil;
}
我通常使用自动布局来做到这一点:
-(void)awakeFromNib{
[super awakeFromNib];
self.backgroundColor = [UIColor clearColor];
CAGradientLayer* gradient = (CAGradientLayer*) self.layer;
gradient.frame = self.bounds;
gradient.colors = [NSArray arrayWithObjects:
(id)[UIColor colorWithRed:0 green:0 blue:0 alpha:0].CGColor,
(id)[UIColor colorWithRed:0 green:0 blue:0 alpha:1].CGColor, nil];
}
+ (Class) layerClass {
return [CAGradientLayer class];
}