如何在径向渐变的情况下切出一个孔 [英] How to cut out a hole with radial gradient in view

查看:115
本文介绍了如何在径向渐变的情况下切出一个孔的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个透明的光孔视图,一个视图叠加了超级视图,并且在封面视图中有一个孔渐变圆形视图,该超级视图仍然可见. 我不知道要实现渐变光孔视图,任何人都可以帮助我

I have a transparent light hole view, a view overlay super view, and there is a hole gradient round view in the cover view, the super view is still visiable. I have no idea to implement the gradient light hole view, anyone can help me

编辑 ===========

EDIT ============

我尝试将封面视图添加到全屏,封面视图背景颜色清晰.然后将自定义CALayer添加到封面视图层作为子层.

I try to add cover view to the full screen, the cover view background color is clear., and add custom CALayer to the cover view layer as sublayer.

封面视图实施方式:

@implementation CoverView

@implementation CoverView

   - (instancetype)initWithFrame:(CGRect)frame {
     self = [super initWithFrame:frame];
     if (self) {
     self.backgroundColor = [UIColor clearColor];
     }
     return self;
   }

    - (void)setGradientHoleFrame:(CGRect)gradientHoleFrame {
     if (!CGRectEqualToRect(_gradientHoleFrame, gradientHoleFrame)) {
    _gradientHoleFrame = gradientHoleFrame;
      [self loadRadialGradientLayer];
     }
   }

   - (void)loadRadialGradientLayer {
    RadialGradientLayer *layer = [[RadialGradientLayer alloc] init];
    layer.frame = self.bounds;
     layer.raidalGradientFrame = self.gradientHoleFrame;
     [layer setNeedsDisplay];
     [self.layer addSublayer:layer];
    }

@end

自定义径向渐变层:

CGFloat const GRADIENT_WIDTH = 10.0f;

@implementation RadialGradientLayer

- (void)setRaidalGradientFrame:(CGRect)raidalGradientFrame {
  if (!CGRectEqualToRect(_raidalGradientFrame, raidalGradientFrame)) {
    _raidalGradientFrame = raidalGradientFrame;
    [self setNeedsDisplay];
  }
}

- (void)drawInContext:(CGContextRef)context {
  CGContextSaveGState(context);
  CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
  CGFloat colours[8] = { 0.0f, 0.0f, 0.0f, 0.0f,     // Clear region colour.
                         0.0f, 0.0f, 0.0f, 0.8 };   // Blur region colour.
  CGFloat locations[2] = { 0.0f, 1.0f };
  CGGradientRef gradient = CGGradientCreateWithColorComponents(colorSpace, colours, locations, 2);
  CGPoint center = CGPointMake(self.raidalGradientFrame.origin.x + self.raidalGradientFrame.size.width / 2,
                               self.raidalGradientFrame.origin.y + self.raidalGradientFrame.size.height / 2);
  CGFloat radius = MIN(self.raidalGradientFrame.size.width / 2, self.raidalGradientFrame.size.height / 2) + GRADIENT_WIDTH;
  CGContextDrawRadialGradient(context, gradient, center, 0.0, center, radius, kCGGradientDrawsAfterEndLocation);

  CGGradientRelease(gradient);
  CGColorSpaceRelease(colorSpace);
}

@end

我使用它:

 CoverView *view = [[CoverView alloc] initWithFrame:[UIScreen mainScreen].bounds];
  // for get hole frame
  CGRect rect = [self.coinPointView.superview convertRect:self.coinPointView.frame toView:view];
  view.gradientHoleFrame = rect;
  [self.tabBarController.view addSubview:view];

最后,我在下面得到结果.

感谢@gbk和@matt

thanks for @gbk and @matt

推荐答案

您可以玩一些游戏并获得

You can play around a little bit and get

要获得这样的结果,我在操场上准备了示例代码-只需将其复制粘贴并尝试.

To achieve such result I prepared sample code in playground - just copy-paste it and try.

import UIKit
import PlaygroundSupport

class RadialGradientLayer: CALayer {

    required override init() {
        super.init()
        needsDisplayOnBoundsChange = true
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }

    required override init(layer: Any) {
        super.init(layer: layer)
    }

    //default colors
    public var colors = [UIColor.red.cgColor, UIColor.clear.cgColor]

    override func draw(in ctx: CGContext) {
        ctx.saveGState()

        let colorSpace = CGColorSpaceCreateDeviceRGB()
        var locations = [CGFloat]()
        for i in 0...colors.count-1 {
            locations.append(CGFloat(i) / CGFloat(colors.count))
        }
        let gradient = CGGradient(colorsSpace: colorSpace, colors: colors as CFArray, locations: locations)
        let center = CGPoint(x: bounds.width / 2.0, y: bounds.height / 2.0)
        let radius = min(bounds.width, bounds.height)
        ctx.drawRadialGradient(gradient!, startCenter: center, startRadius: 0.0, endCenter: center, endRadius: radius, options: CGGradientDrawingOptions(rawValue: 0))
    }    
}

let view = UIView(frame: CGRect(x: 0, y: 0, width: 375, height: 300))
view.backgroundColor = UIColor.green

let label = UILabel(frame: view.bounds)
label.text = "test"
label.font = UIFont.systemFont(ofSize: 30)
label.textAlignment = .center
view.addSubview(label)

let gradientLayer = RadialGradientLayer()
gradientLayer.frame = view.bounds
gradientLayer.colors = [UIColor.clear.cgColor, UIColor.black.cgColor]
gradientLayer.setNeedsDisplay()

view.layer.addSublayer(gradientLayer)


view

这篇关于如何在径向渐变的情况下切出一个孔的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆