Skip to content

Instantly share code, notes, and snippets.

@emrahgunduz
Created September 21, 2016 15:17
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save emrahgunduz/2c7ed2165956b41a7441a89af0efca42 to your computer and use it in GitHub Desktop.
Save emrahgunduz/2c7ed2165956b41a7441a89af0efca42 to your computer and use it in GitHub Desktop.
Playground example for working UIBlurEffect and UIVisualEffectView masking on iOS10 using Swift 3
import UIKit
import PlaygroundSupport
let generalFrame = CGRect(x: 0, y: 0, width: 500, height: 500)
let containerView = UIView(frame: generalFrame)
containerView.backgroundColor = UIColor.black;
PlaygroundPage.current.liveView = containerView
let parentView = UIView(frame: generalFrame)
containerView.addSubview(parentView)
let url = URL(string: "https://static.pexels.com/photos/168066/pexels-photo-168066-large.jpeg")
let data = try Data(contentsOf: url!);
let imageView = UIImageView(frame:parentView.bounds)
imageView.image = UIImage(data: data)
imageView.contentMode = .scaleAspectFill
let maskView = UIView(frame:parentView.bounds)
maskView.backgroundColor = UIColor.black
maskView.layer.mask = {() -> CALayer in
var roundedRect = CGRect (
x: 0.0,
y: 0.0,
width: parentView.bounds.size.width * 0.5,
height: parentView.bounds.size.width * 0.5
);
roundedRect.origin.x = parentView.frame.size.width / 2 - roundedRect.size.width / 2;
roundedRect.origin.y = parentView.frame.size.height / 2 - roundedRect.size.height / 2;
let cornerRadius = roundedRect.size.height / 2.0;
let path = UIBezierPath(rect:parentView.bounds)
let croppedPath = UIBezierPath(roundedRect: roundedRect, cornerRadius: cornerRadius)
path.append(croppedPath)
path.usesEvenOddFillRule = true
let maskLayer = CAShapeLayer()
maskLayer.path = path.cgPath;
maskLayer.fillRule = kCAFillRuleEvenOdd
return maskLayer
}()
let blurView = UIBlurEffect(style: .light)
let effectView = UIVisualEffectView(effect: blurView)
effectView.frame = generalFrame
effectView.mask = maskView
parentView.addSubview(imageView)
parentView.addSubview(effectView)
@teytag
Copy link

teytag commented Nov 1, 2018

Merhaba Emrah,
XCode 10 (Swift 4) playground ile ön bir kod çalışması yapmaktayım. Tek bir UIView üzerine BezierPath ile serbest çizgiler çizmekteyim. İstiyorum ki kırmızı renkteki kalın çizgileri çizerken, beyaz renk zemini olan UIView elementini mask yapsın. Yani, beyaz zeminde çizdiğim çizgiler beyaz zemini silsin. Aşağıdaki kodlamamda tam tersi oluyor. Yardımcı olabilir misin? Erhan Üzümcü

//: A UIKit based Playground for presenting user interface
  
import UIKit
import PlaygroundSupport

class MyViewController : UIViewController {
    
    var lineColor: UIColor!
    var lineWidth: CGFloat!
    var path: UIBezierPath!
    var touchPoint: CGPoint!
    var startingPoint: CGPoint!
    var curvePoint: CGPoint!
    
    override func loadView() {
        // Üzeri çizilerek silinecek olan UIView elementi
        let view = UIView()
        view.backgroundColor = .white
        view.clipsToBounds = true
        view.layer.masksToBounds = true
        view.isMultipleTouchEnabled = false // Birden fazla dokunma ile çizim çizemez
        view.alpha = 0.75 // opacity
        lineColor = UIColor.red // UIColor.red.withAlphaComponent(0.5)
        lineWidth = 32

        self.view = view
    }
    
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        let touch = touches.first
        startingPoint = touch?.location(in: view)
    }
    
    override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
        let touch = touches.first
        touchPoint = touch?.location(in: view)
        print(touchPoint)
        path = UIBezierPath()
        path.move(to: startingPoint)
        path.addLine(to: touchPoint)
        path.flatness = 0.6
        path.usesEvenOddFillRule = true
        //path.fill(with: .clear, alpha: 0.5)
        startingPoint = touchPoint
        drawShapeLayer()
    }
    
    func drawShapeLayer() {
        let shapeLayer = CAShapeLayer()
        shapeLayer.path = path.cgPath
        shapeLayer.frame = view.bounds
        shapeLayer.strokeColor = lineColor.cgColor
        shapeLayer.lineWidth = lineWidth
        shapeLayer.fillColor = lineColor.cgColor
        shapeLayer.lineCap = .round
        shapeLayer.lineJoin = CAShapeLayerLineJoin.miter
        shapeLayer.miterLimit = 10.0
        shapeLayer.fillRule = CAShapeLayerFillRule.evenOdd
        view.layer.addSublayer(shapeLayer)
        view.layer.mask = shapeLayer
        //view.setNeedsDisplay() // Bunu kullanmayınca daha iyi çiziyor
        //print("drawing...")
    }
    
    func clearCanvas() {
        path.removeAllPoints()
        view.layer.sublayers = nil
        view.setNeedsDisplay()
    }
    
    override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
        print("Çizim bitti")
    }
    
}

// Present the view controller in the Live View window
PlaygroundPage.current.liveView = MyViewController()

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment