画线并用UIVisualEffectView填充

时间:2016-11-03 01:07:39

标签: ios swift uiimageview uivisualeffectview

因此绘图线部分已设置:

         prgmName = "@QU@Service";
         prgmPath = "c:\\@QU@\\aquaService.exe";
         prgmMode = "auto";
         s = "sc start " + prgmName;
         cmd_PROMPT(s);

它基本上使用touchesBegan,touchesMoved和touchesEnded,这是func drawLineFrom(_ fromPoint: CGPoint, toPoint: CGPoint) { let blurEffect = UIBlurEffect(style: UIBlurEffectStyle.dark) let blurEffectView = UIVisualEffectView(effect: blurEffect) UIGraphicsBeginImageContextWithOptions(tempImageView.frame.size, false, UIScreen.main.scale) let context = UIGraphicsGetCurrentContext() tempImageView.image?.draw(in: CGRect(x: 0, y: 0, width: tempImageView.frame.size.width, height: tempImageView.frame.size.height), blendMode: .normal, alpha: 1.0) context?.move(to: CGPoint(x: fromPoint.x, y: fromPoint.y)) context?.addLine(to: CGPoint(x: toPoint.x, y: toPoint.y)) context?.setLineCap(.round) context?.setLineWidth(brushWidth) context?.setStrokeColor(blurEffectView(effect: blurEffect)) context?.setBlendMode(.normal) context!.strokePath() var img = UIGraphicsGetImageFromCurrentImageContext() tempImageView.image = img tempImageView.alpha = opacity UIGraphicsEndImageContext() } fromPoint的来源。

就像你已经可以看到我试图用UIVisualEffectView而不是Color填充这一行。显然我的方法并没有真正起作用。 这样做的最佳解决方案是什么?

1 个答案:

答案 0 :(得分:4)

设置

UIVisualEffectView本身并没有任何内容,而是取决于它下面的观点。如果您希望使用UIVisualEffect来提供绘图效果,则应构建您希望在其上绘制图形的视图层次结构。也许类似于带有图像视图的视图,显示一些图像,然后是效果视图,例如:

let imageView = UIImageView(image: UIImage(named: "image.jpg"))
let blurEffect = UIBlurEffect(style: .dark)
let effectView = UIVisualEffectView(effect: blurEffect)
effectView.frame = imageView.bounds
let view = UIView(frame: imageView.bounds)
view.addSubview(imageView)
view.addSubview(effectView)

然后,您需要在此状态下对视图层次结构进行快照。如果它被触摸完全填满,这将像视图一样。您可以通过在UIView上添加扩展程序来实现此目的:

extension UIView
{
    var snapshot: UIImage?
    {
        UIGraphicsBeginImageContextWithOptions(self.bounds.size, false, 0)
        self.drawHierarchy(in: self.bounds, afterScreenUpdates: true)
        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return image
    }
}

let image = view.snapshot!

我们现在可以用UIVisualEffectView替换UIImageView来保存我们的快照视图层次结构:

effectView.removeFromSuperview()
let topImageView = UIImageView(image: image)
view.addSubview(topImageView)

然后,您可以通过声明topImageView属性并将其设置为CAShapeLayer

的遮罩层来屏蔽topImageView到绘图路径
let shapeLayer = CAShapeLayer()

topImageView.layer.mask = shapeLayer

图纸

现在您可以编写drawLine函数:

func drawLine(from fromPoint: CGPoint, to toPoint: CGPoint)
{
    let path: UIBezierPath
    if let layerPath = self.shapeLayer.path
    {
        path = UIBezierPath(cgPath: layerPath)
    }
    else
    {
        path = UIBezierPath()
    }
    path.move(to: fromPoint)
    path.addLine(to: toPoint)
    self.shapeLayer.path = path.cgPath
    self.shapeLayer.lineWidth = brushWidth
    self.shapeLayer.lineCap = "round"
    self.shapeLayer.strokeColor = UIColor.black.cgColor
}

在实时视图的游乐场中,如果没有调用drawLine我的视图如下:

enter image description here

致电:

drawLine(from: CGPoint(x: 0, y: 0), to: CGPoint(x: imageView.frame.maxX, y: imageView.frame.maxY))
drawLine(from: CGPoint(x: 0, y: imageView.frame.maxY), to: CGPoint(x: imageView.frame.maxX, y: 0))

看起来像:

enter image description here

您应该知道这是处理器密集型的,可能无法提供效果。

更新

如果您想稍后更新视图层次结构或视觉效果,可以将UIVisualEffectView保留在视图层次结构中,而不是调用removeFromSuperview并隐藏它。然后重复快照和屏蔽的过程。例如:

func updateMask(with visualEffect: UIVisualEffect)
{
    topImageView.isHidden = true
    effectView.isHidden = false

    effectView.effect = visualEffect
    topImageView.image = view.snapshot

    topImageView.isHidden = false
    effectView.isHidden = true
}

您可以看到我用于游乐场的代码here.