【问题标题】:Positioning content in a CALayer在 CALayer 中定位内容
【发布时间】:2013-01-30 22:57:45
【问题描述】:

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

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

【问题讨论】:

    标签: ios objective-c calayer avcapture


    【解决方案1】:

    尝试使用 .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);
    

    【讨论】:

    • 为这个简单的答案点赞!
    • kCAGravityResizeAspect 可能不会填满整个宽度(取决于高度)。 kCAGravityResizeAspectFill 确实对齐中心 - 而不是顶部。所以我仍然想知道如何拥有 kCAGravityResizeAspectFill 和顶部。
    【解决方案2】:

    尝试使用这组代码:

    将此行添加到图层的初始布局中:

    [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;
    }
    

    【讨论】:

      【解决方案3】:

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

      -(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];
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-12-23
        • 2012-04-21
        • 1970-01-01
        • 2011-10-29
        • 1970-01-01
        • 1970-01-01
        • 2013-03-17
        相关资源
        最近更新 更多