1

如何在 CALayer 中定位内容,使其缩放以适应宽度(保留纵横比)并定位在图层的顶部?

更具体地说,我正在尝试使用 AVCaptureVideoPreviewLayer 来实现此定位。如果我将预览层的 videoGravity 设置为 AVLayerVideoGravityResizeAspectFill ,那么它会填充宽度但将内容垂直居中在框架中(切断顶部和底部)。

4

3 回答 3

2

尝试使用 .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);
于 2015-07-31T07:09:57.587 回答
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;
}
于 2013-02-04T18:07:57.953 回答
0

我通常使用自动布局来做到这一点:

-(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];
}
于 2015-07-31T11:43:31.927 回答